Merge remote-tracking branch 'origin/develop' into bugfix/HOR-3203

This commit is contained in:
hjonathan
2017-05-19 16:21:37 -04:00
546 changed files with 63670 additions and 17583 deletions

View File

@@ -29,9 +29,9 @@
"require": { "require": {
"luracast/restler": "^3.0", "luracast/restler": "^3.0",
"bshaffer/oauth2-server-php": "v1.0", "bshaffer/oauth2-server-php": "v1.0",
"colosa/pmUI": "release/3.2-dev", "colosa/pmUI": "develop-dev",
"colosa/MichelangeloFE": "release/3.2-dev", "colosa/MichelangeloFE": "develop-dev",
"colosa/pmdynaform": "release/3.2-dev", "colosa/pmdynaform": "develop-dev",
"google/apiclient": "1.1.6", "google/apiclient": "1.1.6",
"dapphp/securimage": "^3.6", "dapphp/securimage": "^3.6",
"psr/log":"1.0.0", "psr/log":"1.0.0",

82
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "98d0285e56960342341a1a39337891ad", "content-hash": "a6498bbd2b4058c9da457c82dbc94c85",
"packages": [ "packages": [
{ {
"name": "bshaffer/oauth2-server-php", "name": "bshaffer/oauth2-server-php",
@@ -51,14 +51,14 @@
}, },
{ {
"name": "colosa/MichelangeloFE", "name": "colosa/MichelangeloFE",
"version": "dev-release/3.2", "version": "dev-develop",
"source": { "source": {
"type": "git", "type": "git",
"url": "git@bitbucket.org:colosa/michelangelofe.git", "url": "git@bitbucket.org:colosa/michelangelofe.git",
"reference": "cc19932a095b2232bef7998d2c90b2408ad9be19" "reference": "7e8e9b5094ad4024e88dfdbdfa80291be78ffe1e"
}, },
"require": { "require": {
"colosa/pmui": "release/3.2-dev" "colosa/pmui": "develop-dev"
}, },
"type": "library", "type": "library",
"description": "ProcessMaker Michelangelo Front End", "description": "ProcessMaker Michelangelo Front End",
@@ -66,15 +66,15 @@
"keywords": [ "keywords": [
"js app ProcessMaker" "js app ProcessMaker"
], ],
"time": "2017-04-11 15:29:24" "time": "2017-05-12 18:50:22"
}, },
{ {
"name": "colosa/pmDynaform", "name": "colosa/pmDynaform",
"version": "dev-release/3.2", "version": "dev-develop",
"source": { "source": {
"type": "git", "type": "git",
"url": "git@bitbucket.org:colosa/pmdynaform.git", "url": "git@bitbucket.org:colosa/pmdynaform.git",
"reference": "17ac424d4f51c42c7812fdc117948eef45bddce8" "reference": "d9b3e4633a3d9f5d7514b99b069eb83aa624eacd"
}, },
"type": "library", "type": "library",
"description": "JS Library to render ProcessMaker Dynaforms", "description": "JS Library to render ProcessMaker Dynaforms",
@@ -82,15 +82,15 @@
"keywords": [ "keywords": [
"js lib ProcessMaker Dynaforms" "js lib ProcessMaker Dynaforms"
], ],
"time": "2017-04-11 15:29:14" "time": "2017-05-11 18:06:59"
}, },
{ {
"name": "colosa/pmUI", "name": "colosa/pmUI",
"version": "dev-release/3.2", "version": "dev-develop",
"source": { "source": {
"type": "git", "type": "git",
"url": "git@bitbucket.org:colosa/pmui.git", "url": "git@bitbucket.org:colosa/pmui.git",
"reference": "92a59a33da5d53753da641debf140a1e3babc5f3" "reference": "18aca747094ced65220c744adb0a63773d612f8b"
}, },
"type": "library", "type": "library",
"description": "JS UI Library", "description": "JS UI Library",
@@ -98,7 +98,7 @@
"keywords": [ "keywords": [
"js lib ProcessMaker UI" "js lib ProcessMaker UI"
], ],
"time": "2017-02-24 20:50:27" "time": "2017-05-11 13:11:20"
}, },
{ {
"name": "dapphp/securimage", "name": "dapphp/securimage",
@@ -610,16 +610,16 @@
}, },
{ {
"name": "symfony/config", "name": "symfony/config",
"version": "v2.8.19", "version": "v2.8.20",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/config.git", "url": "https://github.com/symfony/config.git",
"reference": "35b7dfa089d7605eb1fdd46281b3070fb9f38750" "reference": "0b8541d18507d10204a08384640ff6df3c739ebe"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/35b7dfa089d7605eb1fdd46281b3070fb9f38750", "url": "https://api.github.com/repos/symfony/config/zipball/0b8541d18507d10204a08384640ff6df3c739ebe",
"reference": "35b7dfa089d7605eb1fdd46281b3070fb9f38750", "reference": "0b8541d18507d10204a08384640ff6df3c739ebe",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -662,20 +662,20 @@
], ],
"description": "Symfony Config Component", "description": "Symfony Config Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-04-04T15:24:26+00:00" "time": "2017-04-12T14:07:15+00:00"
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v2.8.19", "version": "v2.8.20",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "86407ff20855a5eaa2a7219bd815e9c40a88633e" "reference": "2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/86407ff20855a5eaa2a7219bd815e9c40a88633e", "url": "https://api.github.com/repos/symfony/console/zipball/2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e",
"reference": "86407ff20855a5eaa2a7219bd815e9c40a88633e", "reference": "2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -723,7 +723,7 @@
], ],
"description": "Symfony Console Component", "description": "Symfony Console Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-04-03T20:37:06+00:00" "time": "2017-04-26T01:38:53+00:00"
}, },
{ {
"name": "symfony/debug", "name": "symfony/debug",
@@ -784,16 +784,16 @@
}, },
{ {
"name": "symfony/dependency-injection", "name": "symfony/dependency-injection",
"version": "v2.8.19", "version": "v2.8.20",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/dependency-injection.git", "url": "https://github.com/symfony/dependency-injection.git",
"reference": "14b9d8ae69ac4c74e8f05fee7e0a57039b99c81e" "reference": "e1c722dfe4dd04453aeb6b7a6deefb400c878394"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/14b9d8ae69ac4c74e8f05fee7e0a57039b99c81e", "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e1c722dfe4dd04453aeb6b7a6deefb400c878394",
"reference": "14b9d8ae69ac4c74e8f05fee7e0a57039b99c81e", "reference": "e1c722dfe4dd04453aeb6b7a6deefb400c878394",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -843,20 +843,20 @@
], ],
"description": "Symfony DependencyInjection Component", "description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-04-03T22:14:48+00:00" "time": "2017-04-26T01:38:53+00:00"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v2.8.19", "version": "v2.8.20",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "88b65f0ac25355090e524aba4ceb066025df8bd2" "reference": "7fc8e2b4118ff316550596357325dfd92a51f531"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/88b65f0ac25355090e524aba4ceb066025df8bd2", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7fc8e2b4118ff316550596357325dfd92a51f531",
"reference": "88b65f0ac25355090e524aba4ceb066025df8bd2", "reference": "7fc8e2b4118ff316550596357325dfd92a51f531",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -903,7 +903,7 @@
], ],
"description": "Symfony EventDispatcher Component", "description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-04-03T20:37:06+00:00" "time": "2017-04-26T16:56:54+00:00"
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
@@ -1065,16 +1065,16 @@
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v2.8.19", "version": "v2.8.20",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "047e97a64d609778cadfc76e3a09793696bb19f1" "reference": "32b7c0bffc07772cf1a902e3464ef77117fa07c7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/047e97a64d609778cadfc76e3a09793696bb19f1", "url": "https://api.github.com/repos/symfony/translation/zipball/32b7c0bffc07772cf1a902e3464ef77117fa07c7",
"reference": "047e97a64d609778cadfc76e3a09793696bb19f1", "reference": "32b7c0bffc07772cf1a902e3464ef77117fa07c7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1125,20 +1125,20 @@
], ],
"description": "Symfony Translation Component", "description": "Symfony Translation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-03-21T21:39:01+00:00" "time": "2017-04-12T14:07:15+00:00"
}, },
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v2.8.19", "version": "v2.8.20",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/yaml.git", "url": "https://github.com/symfony/yaml.git",
"reference": "286d84891690b0e2515874717e49360d1c98a703" "reference": "93ccdde79f4b079c7558da4656a3cb1c50c68e02"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/286d84891690b0e2515874717e49360d1c98a703", "url": "https://api.github.com/repos/symfony/yaml/zipball/93ccdde79f4b079c7558da4656a3cb1c50c68e02",
"reference": "286d84891690b0e2515874717e49360d1c98a703", "reference": "93ccdde79f4b079c7558da4656a3cb1c50c68e02",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1174,7 +1174,7 @@
], ],
"description": "Symfony Yaml Component", "description": "Symfony Yaml Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-03-20T09:41:44+00:00" "time": "2017-05-01T14:31:55+00:00"
} }
], ],
"aliases": [], "aliases": [],

View File

@@ -0,0 +1,11 @@
/node_modules
/demo
/doc
/test
/test*.html
/index.html
/mode/*/*test.js
/mode/*/*.html
/mode/index.html
.*
bin

View File

@@ -1,3 +1,4 @@
language: node_js language: node_js
node_js: node_js:
- 0.8 - stable
sudo: false

View File

@@ -2,299 +2,646 @@ List of CodeMirror contributors. Updated before every release.
4r2r 4r2r
Aaron Brooks Aaron Brooks
Abdelouahab
Abe Fettig Abe Fettig
Adam Ahmed
Adam King Adam King
Adam Particka
adanlobato adanlobato
Adán Lobato Adán Lobato
Adrian Aichner
Adrian Heine
Adrien Bertrand
aeroson aeroson
Ahmad Amireh Ahmad Amireh
Ahmad M. Zawawi Ahmad M. Zawawi
ahoward ahoward
Akeksandr Motsjonov Akeksandr Motsjonov
Alasdair Smith
Alberto González Palomo
Alberto Pose Alberto Pose
Albert Xing Albert Xing
Alexander Pavlov Alexander Pavlov
Alexander Schepanovski Alexander Schepanovski
Alexander Shvets
Alexander Solovyov Alexander Solovyov
Alexandre Bique
alexey-k alexey-k
Alex Piggott Alex Piggott
Aliaksei Chapyzhenka
Allen Sarkisyan
Ami Fischman
Amin Shali
Amin Ullah Khan
amshali@google.com
Amsul
amuntean
Amy Amy
Ananya Sen Ananya Sen
anaran
AndersMad AndersMad
Anders Nawroth
Anderson Mesquita Anderson Mesquita
Anders Wåglund
Andrea G
Andreas Reischuck
Andres Taylor
Andre von Houck Andre von Houck
Andrew Cheng
Andrey Fedorov
Andrey Klyuchnikov
Andrey Lushnikov Andrey Lushnikov
Andrey Shchekin
Andy Joslin Andy Joslin
Andy Kimball Andy Kimball
Andy Li Andy Li
Angelo
angelozerr angelozerr
angelo.zerr@gmail.com angelo.zerr@gmail.com
Ankit
Ankit Ahuja Ankit Ahuja
Ansel Santosa Ansel Santosa
Anthony Dugois
anthonygego
Anthony Gégo
Anthony Grimes Anthony Grimes
Anton Kovalyov Anton Kovalyov
Apollo Zhu
AQNOUCH Mohammed
areos areos
Arnab Bose
Arthur Müller
Arun Narasani
as3boyan
atelierbram
AtomicPages LLC AtomicPages LLC
Atul Bhouraskar Atul Bhouraskar
Aurelian Oancea Aurelian Oancea
Axel Lewenhaupt
Barret Rennie
Basarat Ali Syed
Bastian Müller Bastian Müller
belhaj
Bem Jones-Bey
benbro benbro
Beni Cherniavsky-Paskin Beni Cherniavsky-Paskin
Benjamin DeCoste Benjamin DeCoste
Ben Keen Ben Keen
Ben Miller
Ben Mosher
Bernhard Sirlinger
Bert Chang
Bharad
BigBlueHat
Billy Moon
binny
B Krishna Chaitanya
Blaine G
blukat29
boomyjee boomyjee
borawjm borawjm
Brad Metcalf
Brandon Frohs Brandon Frohs
Brandon Wamboldt Brandon Wamboldt
Brett Zamir Brett Zamir
Brian Grinstead
Brian Sletten Brian Sletten
brrd
Bruce Mitchener Bruce Mitchener
Bryan Massoth
Caitlin Potter
Calin Barbat
callodacity
Camilo Roca
Chad Jolly
Chandra Sekhar Pydi Chandra Sekhar Pydi
Charles Skelton Charles Skelton
Cheah Chu Yeow
Chris Coyier Chris Coyier
Chris Ford
Chris Granger Chris Granger
Chris Houseknecht
Chris Lohfink
Chris Morgan Chris Morgan
Chris Smith
Christian Oyarzun
Christian Petrov
Christopher Brown Christopher Brown
Christopher Kramer
Christopher Mitchell
Christopher Pfohl
Chunliang Lyu
ciaranj ciaranj
CodeAnimal CodeAnimal
coderaiser
Cole R Lawrence
ComFreek ComFreek
Curtis Gagliardi
dagsta dagsta
daines
Dale Jung
Dan Bentley
Dan Heberden Dan Heberden
Daniel, Dao Quang Minh Daniel, Dao Quang Minh
Daniele Di Sarli
Daniel Faust Daniel Faust
Daniel Huigens Daniel Huigens
Daniel Kesler
Daniel KJ Daniel KJ
Daniel Neel Daniel Neel
Daniel Parnell Daniel Parnell
Danny Yoo Danny Yoo
darealshinji
Darius Roberts Darius Roberts
Dave Brondsema
Dave Myers
David Barnett
David H. Bronke
David Mignot David Mignot
David Pathakjee David Pathakjee
David Vázquez
David Whittington
deebugger deebugger
Deep Thought Deep Thought
Devin Abbott
Devon Carew
Dick Choi
dignifiedquire
Dimage Sapelkin
Dmitry Kiselyov
domagoj412
Dominator008 Dominator008
Domizio Demichelis Domizio Demichelis
Doug Wikle
Drew Bratcher Drew Bratcher
Drew Hintz Drew Hintz
Drew Khoury Drew Khoury
Drini Cami
Dror BG Dror BG
duralog duralog
eborden eborden
edsharp edsharp
ekhaled ekhaled
Elisée
Emmanuel Schanzer
Enam Mijbah Noor Enam Mijbah Noor
Eric Allam Eric Allam
Erik Welander
eustas eustas
Fabien Dubosson
Fabien O'Carroll
Fabio Zendhi Nagao Fabio Zendhi Nagao
Faiza Alsaied
Fauntleroy Fauntleroy
fbuchinger fbuchinger
feizhang365 feizhang365
Felipe Lalanne Felipe Lalanne
Felix Raab Felix Raab
ficristo
Filip Noetzel Filip Noetzel
Filip Stollár
flack flack
Florian Felten
ForbesLindesay ForbesLindesay
Forbes Lindesay Forbes Lindesay
Ford_Lawnmower Ford_Lawnmower
Forrest Oliphant
Frank Wiegand
Gabriel Gheorghian
Gabriel Horner
Gabriel Nahmias Gabriel Nahmias
galambalazs galambalazs
Gary Sheng
Gautam Mehta Gautam Mehta
Gavin Douglas
gekkoe
Geordie Hall
geowarin
Gerard Braad
Gergely Hegykozi
Giovanni Calò
Glebov Boris
Glenn Jorde Glenn Jorde
Glenn Ruehle Glenn Ruehle
Golevka Golevka
Google Inc.
Gordon Smith Gordon Smith
Grant Skinner
greengiant greengiant
Gregory Koberger
Grzegorz Mazur
Guillaume Massé Guillaume Massé
Guillaume Massé Guillaume Massé
guraga
Gustavo Rodrigues
Hakan Tunc
Hans Engel Hans Engel
Hardest Hardest
Harshvardhan Gupta
Hasan Karahan Hasan Karahan
Hector Oswaldo Caballero
Hendrik Wallbaum
Herculano Campos
Hiroyuki Makino
hitsthings hitsthings
Hocdoc Hocdoc
Hugues Malphettes
Ian Beck Ian Beck
Ian Dickinson Ian Dickinson
Ian Wehrman Ian Wehrman
Ian Wetherbee Ian Wetherbee
Ice White Ice White
ICHIKAWA, Yuji ICHIKAWA, Yuji
idleberg
ilvalle ilvalle
Ingo Richter Ingo Richter
Irakli Gozalishvili Irakli Gozalishvili
Ivan Kurnosov Ivan Kurnosov
Ivoah
Jacob Lee Jacob Lee
Jake Peyser
Jakob Miland
Jakub Vrana Jakub Vrana
Jakub Vrána
James Campos James Campos
James Howard
James Thorne James Thorne
Jamie Hill Jamie Hill
Jamie Morris
Jan Jongboom Jan Jongboom
jankeromnes jankeromnes
Jan Keromnes Jan Keromnes
Jan Odvarko Jan Odvarko
Jan Schär
Jan T. Sott Jan T. Sott
Jared Dean
Jared Forsyth
Jared Jacobs
Jason Jason
Jason Barnabe
Jason Grout Jason Grout
Jason Johnston Jason Johnston
Jason San Jose Jason San Jose
Jason Siefken Jason Siefken
Jaydeep Solanki
Jean Boussier Jean Boussier
Jeff Blaisdell
Jeff Jenkins
jeffkenton jeffkenton
Jeff Pickhardt Jeff Pickhardt
jem (graphite) jem (graphite)
Jeremy Parmenter
Jim
Jim Avery
JobJob
jochenberger
Jochen Berger Jochen Berger
Joel Einbinder
joelpinheiro
Johan Ask Johan Ask
John Connor John Connor
John-David Dalton
John Engler
John Lees-Miller John Lees-Miller
John Snelson John Snelson
John Van Der Loo John Van Der Loo
Jon Ander Peñalba
Jonas Döbertin
Jonathan Malmaud
Jon Gacnik
jongalloway jongalloway
Jon Malmaud Jon Malmaud
Jon Sangster
Joost-Wim Boekesteijn Joost-Wim Boekesteijn
Joseph Pecoraro Joseph Pecoraro
Josh Barnes
Josh Cohen
Josh Soref
Joshua Newman Joshua Newman
Josh Watzman
jots jots
jsoojeon jsoojeon
ju1ius
Juan Benavides Romero Juan Benavides Romero
Jucovschi Constantin Jucovschi Constantin
Juho Vuori Juho Vuori
Julien Rebetez
Justin Andresen
Justin Hileman
jwallers@gmail.com jwallers@gmail.com
kaniga kaniga
karevn
Kayur Patel
Kazuhito Hokamura
Ken Newman Ken Newman
ken restivo
Ken Rockot Ken Rockot
Kevin Earls
Kevin Muret
Kevin Sawicki Kevin Sawicki
Kevin Ushey
Klaus Silveira Klaus Silveira
Koh Zi Han, Cliff Koh Zi Han, Cliff
komakino komakino
Konstantin Lopuhin Konstantin Lopuhin
koops koops
Kris Ciccarello
ks-ifware ks-ifware
kubelsmieci kubelsmieci
KwanEsq
Kyle Kelley
Lanfei
Lanny Lanny
Laszlo Vidacs Laszlo Vidacs
leaf corcoran leaf corcoran
Leonid Khachaturov
Leon Sorokin
Leonya Khachaturov Leonya Khachaturov
Liam Newman Liam Newman
Libo Cannici
LloydMilligan
LM LM
lochel
Lorenzo Stoakes Lorenzo Stoakes
Luca Fabbri
Luciano Longo Luciano Longo
Lu Fangjian
Luke Browning
Luke Granger-Brown
Luke Stagner
lynschinzer lynschinzer
M1cha
Madhura Jayaratne
Maksim Lin Maksim Lin
Maksym Taran Maksym Taran
Malay Majithia
Manideep
Manuel Rego Casasnovas
Marat Dreizin Marat Dreizin
Marcel Gerber
Marcelo Camargo
Marco Aurélio Marco Aurélio
Marco Munizaga
Marcus Bointon
Marek Rudnicki
Marijn Haverbeke Marijn Haverbeke
Mário Gonçalves
Mario Pietsch Mario Pietsch
Mark Anderson
Mark Lentczner Mark Lentczner
Marko Bonaci Marko Bonaci
Mark Peace
Markus Bordihn
Martin Balek Martin Balek
Martín Gaitán Martín Gaitán
Martin Hasoň Martin Hasoň
Martin Hunt
Martin Laine
Martin Zagora
Mason Malone Mason Malone
Mateusz Paprocki Mateusz Paprocki
Mathias Bynens
mats cronqvist mats cronqvist
Matt Gaide
Matthew Bauer
Matthew Beale Matthew Beale
matthewhayes
Matthew Rathbone
Matthias Bussonnier
Matthias BUSSONNIER Matthias BUSSONNIER
Matt McDonald Matt McDonald
Matt Pass Matt Pass
Matt Sacks Matt Sacks
mauricio
Maximilian Hils Maximilian Hils
Maxim Kraev Maxim Kraev
Max Kirsch Max Kirsch
Max Schaefer
Max Xiantu
mbarkhau mbarkhau
McBrainy
mce2
melpon
Metatheos Metatheos
Micah Dubinko Micah Dubinko
Michael
Michael Goderbauer
Michael Grey
Michael Kaminsky
Michael Lehenbauer Michael Lehenbauer
Michael Zhou Michael Zhou
Michal Dorner
Mighty Guava Mighty Guava
Miguel Castillo Miguel Castillo
mihailik
Mike Mike
Mike Brevoort Mike Brevoort
Mike Diaz Mike Diaz
Mike Ivanov Mike Ivanov
Mike Kadin Mike Kadin
Mike Kobit
MinRK MinRK
Miraculix87 Miraculix87
misfo misfo
mkaminsky11
mloginov mloginov
Moritz Schwörer
mps mps
ms
mtaran-google
Mu-An Chiou
Narciso Jaramillo Narciso Jaramillo
Nathan Williams Nathan Williams
ndr
nerbert nerbert
nextrevision
ngn
nguillaumin nguillaumin
Ng Zhi An
Nicholas Bollweg
Nicholas Bollweg (Nick)
Nick Kreeger
Nick Small
Nicolò Ribaudo
Niels van Groningen Niels van Groningen
nightwing
Nikita Beloglazov Nikita Beloglazov
Nikita Vasilyev Nikita Vasilyev
Nikolay Kostov Nikolay Kostov
nilp0inter
Nisarg Jhaveri
nlwillia nlwillia
noragrossman
Norman Rzepka
Oreoluwa Onatemowo
Oskar Segersvärd
pablo pablo
pabloferz
Pablo Zubieta
Page Page
Panupong Pasupat
paris
Paris
Paris Kasidiaris
Patil Arpith
Patrick Stoica
Patrick Strawderman Patrick Strawderman
Paul Garvin Paul Garvin
Paul Ivanov Paul Ivanov
Paul Masson
Pavel
Pavel Feldman Pavel Feldman
Pavel Petržela
Pavel Strashkin Pavel Strashkin
Paweł Bartkiewicz Paweł Bartkiewicz
peteguhl peteguhl
peter
Peter Flynn
peterkroon peterkroon
Peter Kroon Peter Kroon
Philipp A
Philip Stadermann
Pierre Gerold
Piët Delport
Pontus Melke
prasanthj prasanthj
Prasanth J Prasanth J
Prayag Verma
Radek Piórkowski
Rahul Rahul
Rahul Anand
ramwin1
Randall Mason
Randy Burden
Randy Edmunds Randy Edmunds
Rasmus Erik Voel Jensen
ray ratchup
Ray Ratchup
Remi Nyborg
Renaud Durlin
Richard Denton
Richard van der Meer
Richard Z.H. Wang Richard Z.H. Wang
Rishi Goomar
Robert Crossfield
Roberto Abdelkader Martínez Pérez
robertop23 robertop23
Robert Plummer Robert Plummer
Rrandom
Rrrandom
Ruslan Osmanov Ruslan Osmanov
Ryan Petrello
Ryan Prior
sabaca sabaca
Sam Lee
Samuel Ainsworth Samuel Ainsworth
Sam Wilson
sandeepshetty sandeepshetty
Sander AKA Redsandro
Sander Verweij
santec santec
Sascha Peilicke Sascha Peilicke
satamas
satchmorun satchmorun
sathyamoorthi sathyamoorthi
Saul Costa
S. Chris Colbert
SCLINIC\jdecker SCLINIC\jdecker
Scott Aikin
Scott Goodhew
Sebastian Zaha Sebastian Zaha
Sergey Goder
Sergey Tselovalnikov
Se-Won Kim
shaund shaund
shaun gilchrist shaun gilchrist
Shawn A Shawn A
Shea Bunge
sheopory
Shiv Deepak Shiv Deepak
Shmuel Englard Shmuel Englard
Shubham Jain
Siamak Mokhtari
silverwind
sinkuu
snasa
soliton4 soliton4
sonson sonson
spastorelli spastorelli
srajanpaliwal
Stanislav Oaserele Stanislav Oaserele
Stas Kobzar Stas Kobzar
Stefan Borsje Stefan Borsje
Steffen Beyer Steffen Beyer
Steffen Bruchmann
Stephen Lavelle
Steve Champagne
Steve Hoover
Steve O'Hara Steve O'Hara
stoskov stoskov
Stu Kennedy
Sungho Kim
sverweij
Taha Jahangir Taha Jahangir
takamori
Tako Schotanus
Takuji Shimokawa
Tarmil Tarmil
TDaglis
tel
tfjgeorge tfjgeorge
Thaddee Tyl Thaddee Tyl
thanasis
TheHowl
themrmax
think think
Thomas Dvornik Thomas Dvornik
Thomas Kluyver
Thomas Schmid Thomas Schmid
Tim Alby
Tim Baumann Tim Baumann
Timothy Farrell Timothy Farrell
Timothy Gu
Timothy Hatcher Timothy Hatcher
TobiasBg TobiasBg
Todd Berman
Tomas-A Tomas-A
Tomas Varaneckas Tomas Varaneckas
Tom Erik Støwer Tom Erik Støwer
Tom Klancer
Tom MacWright Tom MacWright
Tony Jian Tony Jian
Travis Heppe Travis Heppe
Triangle717
Tristan Tarrant
TSUYUSATO Kitsune
twifkak
VapidWorx
Vestimir Markov Vestimir Markov
vf vf
Victor Bocharsky
Vincent Woo
Volker Mische Volker Mische
Weiyan Shao
wenli wenli
Wes Cossick
Wesley Wiser Wesley Wiser
Will Binns-Smith
Will Dean
William Jamieson William Jamieson
William Stein
Willy
Wojtek Ptak Wojtek Ptak
Wu Cheng-Han
Xavier Mendez Xavier Mendez
Yassin N. Hassan
YNH Webdev YNH Webdev
Yunchi Luo Yunchi Luo
Yuvi Panda Yuvi Panda
Zac Anger
Zachary Dremann Zachary Dremann
Zeno Rocha
Zhang Hao
Ziv
zziuni zziuni
魏鹏刚 魏鹏刚

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,23 @@
# How to contribute # How to contribute
- [Getting help](#getting-help-) - [Getting help](#getting-help)
- [Submitting bug reports](#submitting-bug-reports-) - [Submitting bug reports](#submitting-bug-reports)
- [Contributing code](#contributing-code-) - [Contributing code](#contributing-code)
## Getting help ## Getting help
Community discussion, questions, and informal bug reporting is done on the Community discussion, questions, and informal bug reporting is done on the
[CodeMirror Google group](http://groups.google.com/group/codemirror). [discuss.CodeMirror forum](http://discuss.codemirror.net).
## Submitting bug reports ## Submitting bug reports
The preferred way to report bugs is to use the The preferred way to report bugs is to use the
[GitHub issue tracker](http://github.com/marijnh/CodeMirror/issues). Before [GitHub issue tracker](http://github.com/codemirror/CodeMirror/issues). Before
reporting a bug, read these pointers. reporting a bug, read these pointers.
**Note:** The issue tracker is for *bugs*, not requests for help. Questions **Note:** The issue tracker is for *bugs*, not requests for help. Questions
should be asked on the should be asked on the
[CodeMirror Google group](http://groups.google.com/group/codemirror) instead. [discuss.CodeMirror forum](http://discuss.codemirror.net) instead.
### Reporting bugs effectively ### Reporting bugs effectively
@@ -47,8 +47,12 @@ should be asked on the
## Contributing code ## Contributing code
Note that we are not accepting any new addons or modes into the main
distribution. If you've written such a module, please distribute it as
a separate NPM package.
- Make sure you have a [GitHub Account](https://github.com/signup/free) - Make sure you have a [GitHub Account](https://github.com/signup/free)
- Fork [CodeMirror](https://github.com/marijnh/CodeMirror/) - Fork [CodeMirror](https://github.com/codemirror/CodeMirror/)
([how to fork a repo](https://help.github.com/articles/fork-a-repo)) ([how to fork a repo](https://help.github.com/articles/fork-a-repo))
- Make your changes - Make your changes
- If your changes are easy to test or likely to regress, add tests. - If your changes are easy to test or likely to regress, add tests.
@@ -61,12 +65,28 @@ should be asked on the
- Make sure all tests pass. Visit `test/index.html` in your browser to - Make sure all tests pass. Visit `test/index.html` in your browser to
run them. run them.
- Submit a pull request - Submit a pull request
([how to create a pull request](https://help.github.com/articles/fork-a-repo)) ([how to create a pull request](https://help.github.com/articles/fork-a-repo)).
Don't put more than one feature/fix in a single pull request.
By contributing code to CodeMirror you
- agree to license the contributed code under CodeMirror's [MIT
license](http://codemirror.net/LICENSE).
- confirm that you have the right to contribute and license the code
in question. (Either you hold all rights on the code, or the rights
holder has explicitly granted the right to use it like this,
through a compatible open source license or through a direct
agreement with you.)
### Coding standards ### Coding standards
- 2 spaces per indentation level, no tabs. - 2 spaces per indentation level, no tabs.
- Include semicolons after statements.
- Note that the linter (`bin/lint`) which is run after each commit - Note that the linter (`bin/lint`) which is run after each commit
complains about unused variables and functions. Prefix their names complains about unused variables and functions. Prefix their names
with an underscore to muffle it. with an underscore to muffle it.
- CodeMirror does *not* follow JSHint or JSLint prescribed style.
Patches that try to 'fix' code to pass one of these linters will be
unceremoniously discarded.

View File

@@ -1,4 +1,6 @@
Copyright (C) 2013 by Marijn Haverbeke <marijnh@gmail.com> and others MIT License
Copyright (C) 2017 by Marijn Haverbeke <marijnh@gmail.com> and others
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,11 +1,34 @@
# CodeMirror # CodeMirror
[![Build Status](https://secure.travis-ci.org/marijnh/CodeMirror.png?branch=master)](http://travis-ci.org/marijnh/CodeMirror) [![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror)
[![NPM version](https://badge.fury.io/js/codemirror.png)](http://badge.fury.io/js/codemirror) [![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)
[![Join the chat at https://gitter.im/codemirror/CodeMirror](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/codemirror/CodeMirror)
[Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png?again)](https://marijnhaverbeke.nl/fund/)
CodeMirror is a JavaScript component that provides a code editor in CodeMirror is a versatile text editor implemented in JavaScript for
the browser. When a mode is available for the language you are coding the browser. It is specialized for editing code, and comes with over
in, it will color your code, and optionally help with indentation. 100 language modes and various addons that implement more advanced
editing functionality.
The project page is http://codemirror.net A rich programming API and a CSS theming system are available for
The manual is at http://codemirror.net/doc/manual.html customizing CodeMirror to fit your application, and extending it with
The contributing guidelines are in [CONTRIBUTING.md](https://github.com/marijnh/CodeMirror/blob/master/CONTRIBUTING.md) new functionality.
You can find more information (and the
[manual](http://codemirror.net/doc/manual.html)) on the [project
page](http://codemirror.net). For questions and discussion, use the
[discussion forum](https://discuss.codemirror.net/).
See
[CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md)
for contributing guidelines.
The CodeMirror community aims to be welcoming to everybody. We use the
[Contributor Covenant
(1.1)](http://contributor-covenant.org/version/1/1/0/) as our code of
conduct.
### Quickstart
To build the project, make sure you have Node.js installed (at least version 6)
and then `npm install`. To run, just open `index.html` in your
browser (you don't need to run a webserver). Run the tests with `npm test`.

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
var noOptions = {}; var noOptions = {};
@@ -11,13 +21,45 @@
} }
CodeMirror.commands.toggleComment = function(cm) { CodeMirror.commands.toggleComment = function(cm) {
var from = cm.getCursor("start"), to = cm.getCursor("end"); cm.toggleComment();
cm.uncomment(from, to) || cm.lineComment(from, to);
}; };
CodeMirror.defineExtension("toggleComment", function(options) {
if (!options) options = noOptions;
var cm = this;
var minLine = Infinity, ranges = this.listSelections(), mode = null;
for (var i = ranges.length - 1; i >= 0; i--) {
var from = ranges[i].from(), to = ranges[i].to();
if (from.line >= minLine) continue;
if (to.line >= minLine) to = Pos(minLine, 0);
minLine = from.line;
if (mode == null) {
if (cm.uncomment(from, to, options)) mode = "un";
else { cm.lineComment(from, to, options); mode = "line"; }
} else if (mode == "un") {
cm.uncomment(from, to, options);
} else {
cm.lineComment(from, to, options);
}
}
});
// Rough heuristic to try and detect lines that are part of multi-line string
function probablyInsideString(cm, pos, line) {
return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line)
}
function getMode(cm, pos) {
var mode = cm.getMode()
return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos)
}
CodeMirror.defineExtension("lineComment", function(from, to, options) { CodeMirror.defineExtension("lineComment", function(from, to, options) {
if (!options) options = noOptions; if (!options) options = noOptions;
var self = this, mode = self.getModeAt(from); var self = this, mode = getMode(self, from);
var firstLine = self.getLine(from.line);
if (firstLine == null || probablyInsideString(self, from, firstLine)) return;
var commentString = options.lineComment || mode.lineComment; var commentString = options.lineComment || mode.lineComment;
if (!commentString) { if (!commentString) {
if (options.blockCommentStart || mode.blockCommentStart) { if (options.blockCommentStart || mode.blockCommentStart) {
@@ -26,15 +68,21 @@
} }
return; return;
} }
var firstLine = self.getLine(from.line);
if (firstLine == null) return;
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1); var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
var pad = options.padding == null ? " " : options.padding; var pad = options.padding == null ? " " : options.padding;
var blankLines = options.commentBlankLines || from.line == to.line; var blankLines = options.commentBlankLines || from.line == to.line;
self.operation(function() { self.operation(function() {
if (options.indent) { if (options.indent) {
var baseString = firstLine.slice(0, firstNonWS(firstLine)); var baseString = null;
for (var i = from.line; i < end; ++i) {
var line = self.getLine(i);
var whitespace = line.slice(0, firstNonWS(line));
if (baseString == null || baseString.length > whitespace.length) {
baseString = whitespace;
}
}
for (var i = from.line; i < end; ++i) { for (var i = from.line; i < end; ++i) {
var line = self.getLine(i), cut = baseString.length; var line = self.getLine(i), cut = baseString.length;
if (!blankLines && !nonWS.test(line)) continue; if (!blankLines && !nonWS.test(line)) continue;
@@ -52,7 +100,7 @@
CodeMirror.defineExtension("blockComment", function(from, to, options) { CodeMirror.defineExtension("blockComment", function(from, to, options) {
if (!options) options = noOptions; if (!options) options = noOptions;
var self = this, mode = self.getModeAt(from); var self = this, mode = getMode(self, from);
var startString = options.blockCommentStart || mode.blockCommentStart; var startString = options.blockCommentStart || mode.blockCommentStart;
var endString = options.blockCommentEnd || mode.blockCommentEnd; var endString = options.blockCommentEnd || mode.blockCommentEnd;
if (!startString || !endString) { if (!startString || !endString) {
@@ -60,6 +108,7 @@
self.lineComment(from, to, options); self.lineComment(from, to, options);
return; return;
} }
if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return
var end = Math.min(to.line, self.lastLine()); var end = Math.min(to.line, self.lastLine());
if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end; if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
@@ -85,8 +134,8 @@
CodeMirror.defineExtension("uncomment", function(from, to, options) { CodeMirror.defineExtension("uncomment", function(from, to, options) {
if (!options) options = noOptions; if (!options) options = noOptions;
var self = this, mode = self.getModeAt(from); var self = this, mode = getMode(self, from);
var end = Math.min(to.line, self.lastLine()), start = Math.min(from.line, end); var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
// Try finding line comments // Try finding line comments
var lineString = options.lineComment || mode.lineComment, lines = []; var lineString = options.lineComment || mode.lineComment, lines = [];
@@ -97,7 +146,7 @@
var line = self.getLine(i); var line = self.getLine(i);
var found = line.indexOf(lineString); var found = line.indexOf(lineString);
if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1; if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment; if (found == -1 && nonWS.test(line)) break lineComment;
if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment; if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
lines.push(line); lines.push(line);
} }
@@ -119,17 +168,32 @@
var endString = options.blockCommentEnd || mode.blockCommentEnd; var endString = options.blockCommentEnd || mode.blockCommentEnd;
if (!startString || !endString) return false; if (!startString || !endString) return false;
var lead = options.blockCommentLead || mode.blockCommentLead; var lead = options.blockCommentLead || mode.blockCommentLead;
var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end); var startLine = self.getLine(start), open = startLine.indexOf(startString)
var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString); if (open == -1) return false
var endLine = end == start ? startLine : self.getLine(end)
var close = endLine.indexOf(endString, end == start ? open + startString.length : 0);
if (close == -1 && start != end) { if (close == -1 && start != end) {
endLine = self.getLine(--end); endLine = self.getLine(--end);
close = endLine.lastIndexOf(endString); close = endLine.indexOf(endString);
} }
if (open == -1 || close == -1 || var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1)
!/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) || if (close == -1 ||
!/comment/.test(self.getTokenTypeAt(Pos(end, close + 1)))) !/comment/.test(self.getTokenTypeAt(insideStart)) ||
!/comment/.test(self.getTokenTypeAt(insideEnd)) ||
self.getRange(insideStart, insideEnd, "\n").indexOf(endString) > -1)
return false; return false;
// Avoid killing block comments completely outside the selection.
// Positions of the last startString before the start of the selection, and the first endString after it.
var lastStart = startLine.lastIndexOf(startString, from.ch);
var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
// Positions of the first endString after the end of the selection, and the last startString before it.
firstEnd = endLine.indexOf(endString, to.ch);
var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
self.operation(function() { self.operation(function() {
self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)), self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
Pos(end, close + endString.length)); Pos(end, close + endString.length));
@@ -146,4 +210,4 @@
}); });
return true; return true;
}); });
})(); });

View File

@@ -1,54 +1,85 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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 modes = ["clike", "css", "javascript"]; var modes = ["clike", "css", "javascript"];
for (var i = 0; i < modes.length; ++i) for (var i = 0; i < modes.length; ++i)
CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "}); CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "});
function continueComment(cm) { function continueComment(cm) {
var pos = cm.getCursor(), token = cm.getTokenAt(pos); if (cm.getOption("disableInput")) return CodeMirror.Pass;
if (token.type != "comment" || cm.getOption("disableInput")) return CodeMirror.Pass; var ranges = cm.listSelections(), mode, inserts = [];
var mode = CodeMirror.innerMode(cm.getMode(), token.state).mode; for (var i = 0; i < ranges.length; i++) {
var pos = ranges[i].head, token = cm.getTokenAt(pos);
if (token.type != "comment") return CodeMirror.Pass;
var modeHere = CodeMirror.innerMode(cm.getMode(), token.state).mode;
if (!mode) mode = modeHere;
else if (mode != modeHere) return CodeMirror.Pass;
var insert; var insert = null;
if (mode.blockCommentStart && mode.blockCommentContinue) { if (mode.blockCommentStart && mode.blockCommentContinue) {
var end = token.string.indexOf(mode.blockCommentEnd); var end = token.string.indexOf(mode.blockCommentEnd);
var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found; var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found;
if (end != -1 && end == token.string.length - mode.blockCommentEnd.length) { if (end != -1 && end == token.string.length - mode.blockCommentEnd.length && pos.ch >= end) {
// Comment ended, don't continue it // Comment ended, don't continue it
} else if (token.string.indexOf(mode.blockCommentStart) == 0) { } else if (token.string.indexOf(mode.blockCommentStart) == 0) {
insert = full.slice(0, token.start); insert = full.slice(0, token.start);
if (!/^\s*$/.test(insert)) { if (!/^\s*$/.test(insert)) {
insert = ""; insert = "";
for (var i = 0; i < token.start; ++i) insert += " "; for (var j = 0; j < token.start; ++j) insert += " ";
}
} else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 &&
found + mode.blockCommentContinue.length > token.start &&
/^\s*$/.test(full.slice(0, found))) {
insert = full.slice(0, found);
} }
} else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 && if (insert != null) insert += mode.blockCommentContinue;
found + mode.blockCommentContinue.length > token.start &&
/^\s*$/.test(full.slice(0, found))) {
insert = full.slice(0, found);
} }
if (insert != null) insert += mode.blockCommentContinue; if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) {
} var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment);
if (insert == null && mode.lineComment) { if (found > -1) {
var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment); insert = line.slice(0, found);
if (found > -1) { if (/\S/.test(insert)) insert = null;
insert = line.slice(0, found); else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0];
if (/\S/.test(insert)) insert = null; }
else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0];
} }
if (insert == null) return CodeMirror.Pass;
inserts[i] = "\n" + insert;
} }
if (insert != null) cm.operation(function() {
cm.replaceSelection("\n" + insert, "end"); for (var i = ranges.length - 1; i >= 0; i--)
else cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert");
return CodeMirror.Pass; });
}
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) { CodeMirror.defineOption("continueComments", null, function(cm, val, prev) {
if (prev && prev != CodeMirror.Init) if (prev && prev != CodeMirror.Init)
cm.removeKeyMap("continueComment"); cm.removeKeyMap("continueComment");
if (val) { 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"}; var map = {name: "continueComment"};
map[typeof val == "string" ? val : "Enter"] = continueComment; map[key] = continueComment;
cm.addKeyMap(map); cm.addKeyMap(map);
} }
}); });
})(); });

View File

@@ -1,11 +1,11 @@
.CodeMirror-dialog { .CodeMirror-dialog {
position: absolute; position: absolute;
left: 0; right: 0; left: 0; right: 0;
background: white; background: inherit;
z-index: 15; z-index: 15;
padding: .1em .8em; padding: .1em .8em;
overflow: hidden; overflow: hidden;
color: #333; color: inherit;
} }
.CodeMirror-dialog-top { .CodeMirror-dialog-top {

View File

@@ -1,15 +1,25 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Open simple dialogs on top of an editor. Relies on dialog.css. // Open simple dialogs on top of an editor. Relies on dialog.css.
(function() { (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) {
function dialogDiv(cm, template, bottom) { function dialogDiv(cm, template, bottom) {
var wrap = cm.getWrapperElement(); var wrap = cm.getWrapperElement();
var dialog; var dialog;
dialog = wrap.appendChild(document.createElement("div")); dialog = wrap.appendChild(document.createElement("div"));
if (bottom) { if (bottom)
dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom"; dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
} else { else
dialog.className = "CodeMirror-dialog CodeMirror-dialog-top"; dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
}
if (typeof template == "string") { if (typeof template == "string") {
dialog.innerHTML = template; dialog.innerHTML = template;
} else { // Assuming it's a detached DOM element. } else { // Assuming it's a detached DOM element.
@@ -25,39 +35,61 @@
} }
CodeMirror.defineExtension("openDialog", function(template, callback, options) { CodeMirror.defineExtension("openDialog", function(template, callback, options) {
if (!options) options = {};
closeNotification(this, null); closeNotification(this, null);
var dialog = dialogDiv(this, template, options && options.bottom);
var dialog = dialogDiv(this, template, options.bottom);
var closed = false, me = this; var closed = false, me = this;
function close() { function close(newVal) {
if (closed) return; if (typeof newVal == 'string') {
closed = true; inp.value = newVal;
dialog.parentNode.removeChild(dialog); } else {
if (closed) return;
closed = true;
dialog.parentNode.removeChild(dialog);
me.focus();
if (options.onClose) options.onClose(dialog);
}
} }
var inp = dialog.getElementsByTagName("input")[0], button; var inp = dialog.getElementsByTagName("input")[0], button;
if (inp) { if (inp) {
if (options && options.value) inp.value = options.value; inp.focus();
if (options.value) {
inp.value = options.value;
if (options.selectValueOnOpen !== false) {
inp.select();
}
}
if (options.onInput)
CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
if (options.onKeyUp)
CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
CodeMirror.on(inp, "keydown", function(e) { CodeMirror.on(inp, "keydown", function(e) {
if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
if (e.keyCode == 13 || e.keyCode == 27) { if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
inp.blur();
CodeMirror.e_stop(e); CodeMirror.e_stop(e);
close(); close();
me.focus();
if (e.keyCode == 13) callback(inp.value);
} }
if (e.keyCode == 13) callback(inp.value, e);
}); });
if (options && options.onKeyUp) {
CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
}
if (options && options.value) inp.value = options.value;
inp.focus();
CodeMirror.on(inp, "blur", close);
} else if (button = dialog.getElementsByTagName("button")[0]) { } else if (button = dialog.getElementsByTagName("button")[0]) {
CodeMirror.on(button, "click", function() { CodeMirror.on(button, "click", function() {
close(); close();
me.focus(); me.focus();
}); });
if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
button.focus(); button.focus();
CodeMirror.on(button, "blur", close);
} }
return close; return close;
}); });
@@ -102,8 +134,8 @@
CodeMirror.defineExtension("openNotification", function(template, options) { CodeMirror.defineExtension("openNotification", function(template, options) {
closeNotification(this, close); closeNotification(this, close);
var dialog = dialogDiv(this, template, options && options.bottom); var dialog = dialogDiv(this, template, options && options.bottom);
var duration = options && (options.duration === undefined ? 5000 : options.duration);
var closed = false, doneTimer; var closed = false, doneTimer;
var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
function close() { function close() {
if (closed) return; if (closed) return;
@@ -116,7 +148,10 @@
CodeMirror.e_preventDefault(e); CodeMirror.e_preventDefault(e);
close(); close();
}); });
if (duration) if (duration)
doneTimer = setTimeout(close, options.duration); doneTimer = setTimeout(close, duration);
return close;
}); });
})(); });

View File

@@ -0,0 +1,47 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"
CodeMirror.defineOption("autoRefresh", false, function(cm, val) {
if (cm.state.autoRefresh) {
stopListening(cm, cm.state.autoRefresh)
cm.state.autoRefresh = null
}
if (val && cm.display.wrapper.offsetHeight == 0)
startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250})
})
function startListening(cm, state) {
function check() {
if (cm.display.wrapper.offsetHeight) {
stopListening(cm, state)
if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight)
cm.refresh()
} else {
state.timeout = setTimeout(check, state.delay)
}
}
state.timeout = setTimeout(check, state.delay)
state.hurry = function() {
clearTimeout(state.timeout)
state.timeout = setTimeout(check, 50)
}
CodeMirror.on(window, "mouseup", state.hurry)
CodeMirror.on(window, "keyup", state.hurry)
}
function stopListening(_cm, state) {
clearTimeout(state.timeout)
CodeMirror.off(window, "mouseup", state.hurry)
CodeMirror.off(window, "keyup", state.hurry)
}
});

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
CodeMirror.defineOption("fullScreen", false, function(cm, val, old) { CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
@@ -28,4 +38,4 @@
window.scrollTo(info.scrollLeft, info.scrollTop); window.scrollTo(info.scrollLeft, info.scrollTop);
cm.refresh(); cm.refresh();
} }
})(); });

View File

@@ -0,0 +1,123 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineExtension("addPanel", function(node, options) {
options = options || {};
if (!this.state.panels) initPanels(this);
var info = this.state.panels;
var wrapper = info.wrapper;
var cmWrapper = this.getWrapperElement();
if (options.after instanceof Panel && !options.after.cleared) {
wrapper.insertBefore(node, options.before.node.nextSibling);
} else if (options.before instanceof Panel && !options.before.cleared) {
wrapper.insertBefore(node, options.before.node);
} else if (options.replace instanceof Panel && !options.replace.cleared) {
wrapper.insertBefore(node, options.replace.node);
options.replace.clear();
} else if (options.position == "bottom") {
wrapper.appendChild(node);
} else if (options.position == "before-bottom") {
wrapper.insertBefore(node, cmWrapper.nextSibling);
} else if (options.position == "after-top") {
wrapper.insertBefore(node, cmWrapper);
} else {
wrapper.insertBefore(node, wrapper.firstChild);
}
var height = (options && options.height) || node.offsetHeight;
this._setSize(null, info.heightLeft -= height);
info.panels++;
if (options.stable && isAtTop(this, node))
this.scrollTo(null, this.getScrollInfo().top + height)
return new Panel(this, node, options, height);
});
function Panel(cm, node, options, height) {
this.cm = cm;
this.node = node;
this.options = options;
this.height = height;
this.cleared = false;
}
Panel.prototype.clear = function() {
if (this.cleared) return;
this.cleared = true;
var info = this.cm.state.panels;
this.cm._setSize(null, info.heightLeft += this.height);
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);
};
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;
};
function initPanels(cm) {
var wrap = cm.getWrapperElement();
var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle;
var height = parseInt(style.height);
var info = cm.state.panels = {
setHeight: wrap.style.height,
heightLeft: height,
panels: 0,
wrapper: document.createElement("div")
};
wrap.parentNode.insertBefore(info.wrapper, wrap);
var hasFocus = cm.hasFocus();
info.wrapper.appendChild(wrap);
if (hasFocus) cm.focus();
cm._setSize = cm.setSize;
if (height != null) cm.setSize = function(width, newHeight) {
if (newHeight == null) return this._setSize(width, newHeight);
info.setHeight = newHeight;
if (typeof newHeight != "number") {
var px = /^(\d+\.?\d*)px$/.exec(newHeight);
if (px) {
newHeight = Number(px[1]);
} else {
info.wrapper.style.height = newHeight;
newHeight = info.wrapper.offsetHeight;
info.wrapper.style.height = "";
}
}
cm._setSize(width, info.heightLeft += (newHeight - height));
height = newHeight;
};
}
function removePanels(cm) {
var info = cm.state.panels;
cm.state.panels = null;
var wrap = cm.getWrapperElement();
info.wrapper.parentNode.replaceChild(wrap, info.wrapper);
wrap.style.height = info.setHeight;
cm.setSize = cm._setSize;
cm.setSize();
}
function isAtTop(cm, dom) {
for (var sibling = dom.nextSibling; sibling; sibling = sibling.nextSibling)
if (sibling == cm.getWrapperElement()) return true
return false
}
});

View File

@@ -1,13 +1,25 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineOption("placeholder", "", function(cm, val, old) { CodeMirror.defineOption("placeholder", "", function(cm, val, old) {
var prev = old && old != CodeMirror.Init; var prev = old && old != CodeMirror.Init;
if (val && !prev) { if (val && !prev) {
cm.on("blur", onBlur); cm.on("blur", onBlur);
cm.on("change", onChange); cm.on("change", onChange);
cm.on("swapDoc", onChange);
onChange(cm); onChange(cm);
} else if (!val && prev) { } else if (!val && prev) {
cm.off("blur", onBlur); cm.off("blur", onBlur);
cm.off("change", onChange); cm.off("change", onChange);
cm.off("swapDoc", onChange);
clearPlaceholder(cm); clearPlaceholder(cm);
var wrapper = cm.getWrapperElement(); var wrapper = cm.getWrapperElement();
wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
@@ -27,7 +39,9 @@
var elt = cm.state.placeholder = document.createElement("pre"); var elt = cm.state.placeholder = document.createElement("pre");
elt.style.cssText = "height: 0; overflow: visible"; elt.style.cssText = "height: 0; overflow: visible";
elt.className = "CodeMirror-placeholder"; elt.className = "CodeMirror-placeholder";
elt.appendChild(document.createTextNode(cm.getOption("placeholder"))); var placeHolder = cm.getOption("placeholder")
if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
elt.appendChild(placeHolder)
cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
} }
@@ -45,4 +59,4 @@
function isEmpty(cm) { function isEmpty(cm) {
return (cm.lineCount() === 1) && (cm.getLine(0) === ""); return (cm.lineCount() === 1) && (cm.getLine(0) === "");
} }
})(); });

View File

@@ -0,0 +1,51 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.defineOption("rulers", false, function(cm, val) {
if (cm.state.rulerDiv) {
cm.state.rulerDiv.parentElement.removeChild(cm.state.rulerDiv)
cm.state.rulerDiv = null
cm.off("refresh", drawRulers)
}
if (val && val.length) {
cm.state.rulerDiv = cm.display.lineSpace.parentElement.insertBefore(document.createElement("div"), cm.display.lineSpace)
cm.state.rulerDiv.className = "CodeMirror-rulers"
drawRulers(cm)
cm.on("refresh", drawRulers)
}
});
function drawRulers(cm) {
cm.state.rulerDiv.textContent = ""
var val = cm.getOption("rulers");
var cw = cm.defaultCharWidth();
var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left;
cm.state.rulerDiv.style.minHeight = (cm.display.scroller.offsetHeight + 30) + "px";
for (var i = 0; i < val.length; i++) {
var elt = document.createElement("div");
elt.className = "CodeMirror-ruler";
var col, conf = val[i];
if (typeof conf == "number") {
col = conf;
} else {
col = conf.column;
if (conf.className) elt.className += " " + conf.className;
if (conf.color) elt.style.borderColor = conf.color;
if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle;
if (conf.width) elt.style.borderLeftWidth = conf.width;
}
elt.style.left = (left + col * cw) + "px";
cm.state.rulerDiv.appendChild(elt)
}
}
});

View File

@@ -1,84 +1,202 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
var DEFAULT_BRACKETS = "()[]{}''\"\""; // Distributed under an MIT license: http://codemirror.net/LICENSE
var DEFAULT_EXPLODE_ON_ENTER = "[]{}";
var SPACE_CHAR_REGEX = /\s/; (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 defaults = {
pairs: "()[]{}''\"\"",
triples: "",
explode: "[]{}"
};
var Pos = CodeMirror.Pos;
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
if (old != CodeMirror.Init && old) if (old && old != CodeMirror.Init) {
cm.removeKeyMap("autoCloseBrackets"); cm.removeKeyMap(keyMap);
if (!val) return; cm.state.closeBrackets = null;
var pairs = DEFAULT_BRACKETS, explode = DEFAULT_EXPLODE_ON_ENTER; }
if (typeof val == "string") pairs = val; if (val) {
else if (typeof val == "object") { cm.state.closeBrackets = val;
if (val.pairs != null) pairs = val.pairs; cm.addKeyMap(keyMap);
if (val.explode != null) explode = val.explode;
} }
var map = buildKeymap(pairs);
if (explode) map.Enter = buildExplodeHandler(explode);
cm.addKeyMap(map);
}); });
function getOption(conf, name) {
if (name == "pairs" && typeof conf == "string") return conf;
if (typeof conf == "object" && conf[name] != null) return conf[name];
return defaults[name];
}
var bind = defaults.pairs + "`";
var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
for (var i = 0; i < bind.length; i++)
keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i));
function handler(ch) {
return function(cm) { return handleChar(cm, ch); };
}
function getConfig(cm) {
var deflt = cm.state.closeBrackets;
if (!deflt || deflt.override) return deflt;
var mode = cm.getModeAt(cm.getCursor());
return mode.closeBrackets || deflt;
}
function handleBackspace(cm) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
var pairs = getOption(conf, "pairs");
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
for (var i = ranges.length - 1; i >= 0; i--) {
var cur = ranges[i].head;
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
}
}
function handleEnter(cm) {
var conf = getConfig(cm);
var explode = conf && getOption(conf, "explode");
if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
cm.replaceSelection("\n\n", null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var line = ranges[i].head.line;
cm.indentLine(line, null, true);
cm.indentLine(line + 1, null, true);
}
});
}
function contractSelection(sel) {
var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
}
function handleChar(cm, ch) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
var pairs = getOption(conf, "pairs");
var pos = pairs.indexOf(ch);
if (pos == -1) return CodeMirror.Pass;
var triples = getOption(conf, "triples");
var identical = pairs.charAt(pos + 1) == ch;
var ranges = cm.listSelections();
var opening = pos % 2 == 0;
var type;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], cur = range.head, curType;
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
if (opening && !range.empty()) {
curType = "surround";
} else if ((identical || !opening) && next == ch) {
if (identical && stringStartsAfter(cm, cur))
curType = "both";
else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
curType = "skipThree";
else
curType = "skip";
} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&
(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {
curType = "addFour";
} else if (identical) {
if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both";
else return CodeMirror.Pass;
} else if (opening && (cm.getLine(cur.line).length == cur.ch ||
isClosingBracket(next, pairs) ||
/\s/.test(next))) {
curType = "both";
} else {
return CodeMirror.Pass;
}
if (!type) type = curType;
else if (type != curType) return CodeMirror.Pass;
}
var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
var right = pos % 2 ? ch : pairs.charAt(pos + 1);
cm.operation(function() {
if (type == "skip") {
cm.execCommand("goCharRight");
} else if (type == "skipThree") {
for (var i = 0; i < 3; i++)
cm.execCommand("goCharRight");
} else if (type == "surround") {
var sels = cm.getSelections();
for (var i = 0; i < sels.length; i++)
sels[i] = left + sels[i] + right;
cm.replaceSelections(sels, "around");
sels = cm.listSelections().slice();
for (var i = 0; i < sels.length; i++)
sels[i] = contractSelection(sels[i]);
cm.setSelections(sels);
} else if (type == "both") {
cm.replaceSelection(left + right, null);
cm.triggerElectric(left + right);
cm.execCommand("goCharLeft");
} else if (type == "addFour") {
cm.replaceSelection(left + left + left + left, "before");
cm.execCommand("goCharRight");
}
});
}
function isClosingBracket(ch, pairs) {
var pos = pairs.lastIndexOf(ch);
return pos > -1 && pos % 2 == 1;
}
function charsAround(cm, pos) { function charsAround(cm, pos) {
var str = cm.getRange(CodeMirror.Pos(pos.line, pos.ch - 1), var str = cm.getRange(Pos(pos.line, pos.ch - 1),
CodeMirror.Pos(pos.line, pos.ch + 1)); Pos(pos.line, pos.ch + 1));
return str.length == 2 ? str : null; return str.length == 2 ? str : null;
} }
function buildKeymap(pairs) { // Project the token type that will exists after the given char is
var map = { // typed, and use it to determine whether it would cause the start
name : "autoCloseBrackets", // of a string token.
Backspace: function(cm) { function enteringString(cm, pos, ch) {
if (cm.somethingSelected() || cm.getOption("disableInput")) return CodeMirror.Pass; var line = cm.getLine(pos.line);
var cur = cm.getCursor(), around = charsAround(cm, cur); var token = cm.getTokenAt(pos);
if (around && pairs.indexOf(around) % 2 == 0) if (/\bstring2?\b/.test(token.type) || stringStartsAfter(cm, pos)) return false;
cm.replaceRange("", CodeMirror.Pos(cur.line, cur.ch - 1), CodeMirror.Pos(cur.line, cur.ch + 1)); var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4);
else stream.pos = stream.start = token.start;
return CodeMirror.Pass; for (;;) {
} var type1 = cm.getMode().token(stream, token.state);
}; if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1);
var closingBrackets = ""; stream.start = stream.pos;
for (var i = 0; i < pairs.length; i += 2) (function(left, right) { }
if (left != right) closingBrackets += right;
function surround(cm) {
var selection = cm.getSelection();
cm.replaceSelection(left + selection + right);
}
function maybeOverwrite(cm) {
var cur = cm.getCursor(), ahead = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1));
if (ahead != right || cm.somethingSelected()) return CodeMirror.Pass;
else cm.execCommand("goCharRight");
}
map["'" + left + "'"] = function(cm) {
if (left == "'" && cm.getTokenAt(cm.getCursor()).type == "comment" ||
cm.getOption("disableInput"))
return CodeMirror.Pass;
if (cm.somethingSelected()) return surround(cm);
if (left == right && maybeOverwrite(cm) != CodeMirror.Pass) return;
var cur = cm.getCursor(), ahead = CodeMirror.Pos(cur.line, cur.ch + 1);
var line = cm.getLine(cur.line), nextChar = line.charAt(cur.ch), curChar = cur.ch > 0 ? line.charAt(cur.ch - 1) : "";
if (left == right && CodeMirror.isWordChar(curChar))
return CodeMirror.Pass;
if (line.length == cur.ch || closingBrackets.indexOf(nextChar) >= 0 || SPACE_CHAR_REGEX.test(nextChar))
cm.replaceSelection(left + right, {head: ahead, anchor: ahead});
else
return CodeMirror.Pass;
};
if (left != right) map["'" + right + "'"] = maybeOverwrite;
})(pairs.charAt(i), pairs.charAt(i + 1));
return map;
} }
function buildExplodeHandler(pairs) { function stringStartsAfter(cm, pos) {
return function(cm) { var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
var cur = cm.getCursor(), around = charsAround(cm, cur); return /\bstring/.test(token.type) && token.start == pos.ch
if (!around || pairs.indexOf(around) % 2 != 0 || cm.getOption("disableInput"))
return CodeMirror.Pass;
cm.operation(function() {
var newPos = CodeMirror.Pos(cur.line + 1, 0);
cm.replaceSelection("\n\n", {anchor: newPos, head: newPos}, "+input");
cm.indentLine(cur.line + 1, null, true);
cm.indentLine(cur.line + 2, null, true);
});
};
} }
})(); });

View File

@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
/** /**
* Tag-closer extension for CodeMirror. * Tag-closer extension for CodeMirror.
* *
@@ -22,7 +25,14 @@
* See demos/closetag.html for a usage example. * See demos/closetag.html for a usage example.
*/ */
(function() { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../fold/xml-fold"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) { CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) {
if (old != CodeMirror.Init && old) if (old != CodeMirror.Init && old)
cm.removeKeyMap("autoCloseTags"); cm.removeKeyMap("autoCloseTags");
@@ -41,53 +51,119 @@
"h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"]; "h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
function autoCloseGT(cm) { function autoCloseGT(cm) {
var pos = cm.getCursor(), tok = cm.getTokenAt(pos); if (cm.getOption("disableInput")) return CodeMirror.Pass;
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; var ranges = cm.listSelections(), replacements = [];
if (inner.mode.name != "xml" || !state.tagName || cm.getOption("disableInput")) return CodeMirror.Pass; for (var i = 0; i < ranges.length; i++) {
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 opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html"; var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html";
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose); var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent); var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
var tagName = state.tagName; var tagName = state.tagName;
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch); if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
var lowerTagName = tagName.toLowerCase(); var lowerTagName = tagName.toLowerCase();
// Don't process the '>' at the end of an end-tag or self-closing tag // Don't process the '>' at the end of an end-tag or self-closing tag
if (!tagName || if (!tagName ||
tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) || 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.type == "tag" && state.type == "closeTag" ||
tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName /> tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 || dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 ||
CodeMirror.scanForClosingTag && CodeMirror.scanForClosingTag(cm, pos, tagName, closingTagExists(cm, tagName, pos, state, true))
Math.min(cm.lastLine() + 1, pos.line + 50))) return CodeMirror.Pass;
return CodeMirror.Pass;
var doIndent = indentTags && indexOf(indentTags, lowerTagName) > -1; var indent = indentTags && indexOf(indentTags, lowerTagName) > -1;
var curPos = doIndent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1); replacements[i] = {indent: indent,
cm.replaceSelection(">" + (doIndent ? "\n\n" : "") + "</" + tagName + ">", text: ">" + (indent ? "\n\n" : "") + "</" + tagName + ">",
{head: curPos, anchor: curPos}); newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)};
if (doIndent) { }
cm.indentLine(pos.line + 1, null, true);
cm.indentLine(pos.line + 2, null); for (var i = ranges.length - 1; i >= 0; i--) {
var info = replacements[i];
cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert");
var sel = cm.listSelections().slice(0);
sel[i] = {head: info.newPos, anchor: info.newPos};
cm.setSelections(sel);
if (info.indent) {
cm.indentLine(info.newPos.line, null, true);
cm.indentLine(info.newPos.line + 1, null, true);
}
} }
} }
function autoCloseSlash(cm) { function autoCloseCurrent(cm, typingSlash) {
var pos = cm.getCursor(), tok = cm.getTokenAt(pos); var ranges = cm.listSelections(), replacements = [];
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; var head = typingSlash ? "/" : "</";
if (tok.type == "string" || tok.string.charAt(0) != "<" || for (var i = 0; i < ranges.length; i++) {
tok.start != pos.ch - 1 || inner.mode.name != "xml" || if (!ranges[i].empty()) return CodeMirror.Pass;
cm.getOption("disableInput")) var pos = ranges[i].head, tok = cm.getTokenAt(pos);
return CodeMirror.Pass; var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
var tagName = state.context && state.context.tagName; tok.start != pos.ch - 1))
if (tagName) cm.replaceSelection("/" + tagName + ">", "end"); return CodeMirror.Pass;
// Kludge to get around the fact that we are not in XML mode
// 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;
} else {
if (!state.context || !state.context.tagName ||
closingTagExists(cm, state.context.tagName, pos, state))
return CodeMirror.Pass;
replacement = head + state.context.tagName;
}
if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
replacements[i] = replacement;
}
cm.replaceSelections(replacements);
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++)
if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
cm.indentLine(ranges[i].head.line);
} }
function autoCloseSlash(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
return autoCloseCurrent(cm, true);
}
CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
function indexOf(collection, elt) { function indexOf(collection, elt) {
if (collection.indexOf) return collection.indexOf(elt); if (collection.indexOf) return collection.indexOf(elt);
for (var i = 0, e = collection.length; i < e; ++i) for (var i = 0, e = collection.length; i < e; ++i)
if (collection[i] == elt) return i; if (collection[i] == elt) return i;
return -1; return -1;
} }
})();
// 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) {
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;
pos = nextClose.to;
for (var i = 1; i < onCx; i++) {
var next = CodeMirror.scanForClosingTag(cm, pos, null, end);
if (!next || next.tag != tagName) return false;
pos = next.to;
}
return true;
}
});

View File

@@ -1,27 +1,51 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
'use strict'; // Distributed under an MIT license: http://codemirror.net/LICENSE
var listRE = /^(\s*)([*+-]|(\d+)\.)(\s*)/, (function(mod) {
unorderedBullets = '*+-'; 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) {
"use strict";
var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
unorderedListRE = /[*+-]\s/;
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass; if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), replacements = [];
for (var i = 0; i < ranges.length; i++) {
var pos = ranges[i].head;
var eolState = cm.getStateAfter(pos.line);
var inList = eolState.list !== false;
var inQuote = eolState.quote !== 0;
var pos = cm.getCursor(), var line = cm.getLine(pos.line), match = listRE.exec(line);
inList = cm.getStateAfter(pos.line).list !== false, if (!ranges[i].empty() || (!inList && !inQuote) || !match) {
match; cm.execCommand("newlineAndIndent");
return;
}
if (emptyListRE.test(line)) {
if (!/>\s*$/.test(line)) cm.replaceRange("", {
line: pos.line, ch: 0
}, {
line: pos.line, ch: pos.ch + 1
});
replacements[i] = "\n";
} else {
var indent = match[1], after = match[5];
var bullet = unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0
? match[2].replace("x", " ")
: (parseInt(match[3], 10) + 1) + match[4];
if (!inList || !(match = cm.getLine(pos.line).match(listRE))) { replacements[i] = "\n" + indent + bullet + after;
cm.execCommand('newlineAndIndent'); }
return;
} }
var indent = match[1], after = match[4]; cm.replaceSelections(replacements);
var bullet = unorderedBullets.indexOf(match[2]) >= 0
? match[2]
: (parseInt(match[3], 10) + 1) + '.';
cm.replaceSelection('\n' + indent + bullet + after, 'end');
}; };
});
}());

View File

@@ -1,79 +1,111 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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 ie_lt8 = /MSIE \d/.test(navigator.userAgent) && var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
(document.documentMode == null || document.documentMode < 8); (document.documentMode == null || document.documentMode < 8);
var Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos;
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
function findMatchingBracket(cm, where, strict) {
var state = cm.state.matchBrackets;
var maxScanLen = (state && state.maxScanLineLength) || 10000;
var maxScanLines = (state && state.maxScanLines) || 100;
var cur = where || cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1; function findMatchingBracket(cm, where, strict, config) {
var line = cm.getLineHandle(where.line), pos = where.ch - 1;
var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
if (!match) return null; if (!match) return null;
var forward = match.charAt(1) == ">", d = forward ? 1 : -1; var dir = match.charAt(1) == ">" ? 1 : -1;
if (strict && forward != (pos == cur.ch)) return null; if (strict && (dir > 0) != (pos == where.ch)) return null;
var style = cm.getTokenTypeAt(Pos(cur.line, pos + 1)); var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
var stack = [line.text.charAt(pos)], re = /[(){}[\]]/; var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
function scan(line, lineNo, start) { if (found == null) return null;
if (!line.text) return; return {from: Pos(where.line, pos), to: found && found.pos,
var pos = forward ? 0 : line.text.length - 1, end = forward ? line.text.length : -1; match: found && found.ch == match.charAt(0), forward: dir > 0};
if (line.text.length > maxScanLen) return null; }
if (start != null) pos = start + d;
for (; pos != end; pos += d) { // bracketRegex is used to specify which type of bracket to scan
var ch = line.text.charAt(pos); // should be a regexp, e.g. /[[\]]/
if (re.test(ch) && cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style) { //
// Note: If "where" is on an open bracket, then this bracket is ignored.
//
// Returns false when no bracket was found, null when it reached
// maxScanLines and gave up
function scanForBracket(cm, where, dir, style, config) {
var maxScanLen = (config && config.maxScanLineLength) || 10000;
var maxScanLines = (config && config.maxScanLines) || 1000;
var stack = [];
var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/;
var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
: Math.max(cm.firstLine() - 1, where.line - maxScanLines);
for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
var line = cm.getLine(lineNo);
if (!line) continue;
var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
if (line.length > maxScanLen) continue;
if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
for (; pos != end; pos += dir) {
var ch = line.charAt(pos);
if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
var match = matching[ch]; var match = matching[ch];
if (match.charAt(1) == ">" == forward) stack.push(ch); if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false}; else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
else if (!stack.length) return {pos: pos, match: true}; else stack.pop();
} }
} }
} }
for (var i = cur.line, found, e = forward ? Math.min(i + maxScanLines, cm.lineCount()) : Math.max(-1, i - maxScanLines); i != e; i+=d) { return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
if (i == cur.line) found = scan(line, i, pos);
else found = scan(cm.getLineHandle(i), i);
if (found) break;
}
return {from: Pos(cur.line, pos), to: found && Pos(i, found.pos),
match: found && found.match, forward: forward};
} }
function matchBrackets(cm, autoclear) { function matchBrackets(cm, autoclear, config) {
// Disable brace matching in long lines, since it'll cause hugely slow updates // Disable brace matching in long lines, since it'll cause hugely slow updates
var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
var found = findMatchingBracket(cm); var marks = [], ranges = cm.listSelections();
if (!found || cm.getLine(found.from.line).length > maxHighlightLen || for (var i = 0; i < ranges.length; i++) {
found.to && cm.getLine(found.to.line).length > maxHighlightLen) var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);
return; if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
}
}
var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; if (marks.length) {
var one = cm.markText(found.from, Pos(found.from.line, found.from.ch + 1), {className: style}); // Kludge to work around the IE bug from issue #1193, where text
var two = found.to && cm.markText(found.to, Pos(found.to.line, found.to.ch + 1), {className: style}); // input stops going to the textare whever this fires.
// Kludge to work around the IE bug from issue #1193, where text if (ie_lt8 && cm.state.focused) cm.focus();
// input stops going to the textarea whenever this fires.
if (ie_lt8 && cm.state.focused) cm.display.input.focus(); var clear = function() {
var clear = function() { cm.operation(function() {
cm.operation(function() { one.clear(); two && two.clear(); }); for (var i = 0; i < marks.length; i++) marks[i].clear();
}; });
if (autoclear) setTimeout(clear, 800); };
else return clear; if (autoclear) setTimeout(clear, 800);
else return clear;
}
} }
var currentlyHighlighted = null; var currentlyHighlighted = null;
function doMatchBrackets(cm) { function doMatchBrackets(cm) {
cm.operation(function() { cm.operation(function() {
if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
if (!cm.somethingSelected()) currentlyHighlighted = matchBrackets(cm, false); currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
}); });
} }
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchBrackets); cm.off("cursorActivity", doMatchBrackets);
if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
}
if (val) { if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {}; cm.state.matchBrackets = typeof val == "object" ? val : {};
cm.on("cursorActivity", doMatchBrackets); cm.on("cursorActivity", doMatchBrackets);
@@ -81,7 +113,10 @@
}); });
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
CodeMirror.defineExtension("findMatchingBracket", function(pos, strict){ CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){
return findMatchingBracket(this, pos, strict); return findMatchingBracket(this, pos, strict, config);
}); });
})(); CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
return scanForBracket(this, pos, dir, style, config);
});
});

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../fold/xml-fold"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict"; "use strict";
CodeMirror.defineOption("matchTags", false, function(cm, val, old) { CodeMirror.defineOption("matchTags", false, function(cm, val, old) {
@@ -50,7 +60,7 @@
var found = CodeMirror.findMatchingTag(cm, cm.getCursor()); var found = CodeMirror.findMatchingTag(cm, cm.getCursor());
if (found) { if (found) {
var other = found.at == "close" ? found.open : found.close; var other = found.at == "close" ? found.open : found.close;
if (other) cm.setSelection(other.to, other.from); if (other) cm.extendSelection(other.to, other.from);
} }
}; };
})(); });

View File

@@ -1,15 +1,27 @@
CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) { // CodeMirror, copyright (c) by Marijn Haverbeke and others
if (prev == CodeMirror.Init) prev = false; // Distributed under an MIT license: http://codemirror.net/LICENSE
if (prev && !val)
cm.removeOverlay("trailingspace"); (function(mod) {
else if (!prev && val) if (typeof exports == "object" && typeof module == "object") // CommonJS
cm.addOverlay({ mod(require("../../lib/codemirror"));
token: function(stream) { else if (typeof define == "function" && define.amd) // AMD
for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {} define(["../../lib/codemirror"], mod);
if (i > stream.pos) { stream.pos = i; return null; } else // Plain browser env
stream.pos = l; mod(CodeMirror);
return "trailingspace"; })(function(CodeMirror) {
}, CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) {
name: "trailingspace" if (prev == CodeMirror.Init) prev = false;
}); if (prev && !val)
cm.removeOverlay("trailingspace");
else if (!prev && val)
cm.addOverlay({
token: function(stream) {
for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {}
if (i > stream.pos) { stream.pos = i; return null; }
stream.pos = l;
return "trailingspace";
},
name: "trailingspace"
});
});
}); });

View File

@@ -1,6 +1,19 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.registerHelper("fold", "brace", function(cm, start) { CodeMirror.registerHelper("fold", "brace", function(cm, start) {
var line = start.line, lineText = cm.getLine(line); var line = start.line, lineText = cm.getLine(line);
var startCh, tokenType; var tokenType;
function findOpening(openCh) { function findOpening(openCh) {
for (var at = start.ch, pass = 0;;) { for (var at = start.ch, pass = 0;;) {
@@ -45,7 +58,6 @@ CodeMirror.registerHelper("fold", "brace", function(cm, start) {
return {from: CodeMirror.Pos(line, startCh), return {from: CodeMirror.Pos(line, startCh),
to: CodeMirror.Pos(end, endCh)}; to: CodeMirror.Pos(end, endCh)};
}); });
CodeMirror.braceRangeFinder = CodeMirror.fold.brace; // deprecated
CodeMirror.registerHelper("fold", "import", function(cm, start) { CodeMirror.registerHelper("fold", "import", function(cm, start) {
function hasImport(line) { function hasImport(line) {
@@ -60,17 +72,16 @@ CodeMirror.registerHelper("fold", "import", function(cm, start) {
} }
} }
var start = start.line, has = hasImport(start), prev; var startLine = start.line, has = hasImport(startLine), prev;
if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1)) if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1))
return null; return null;
for (var end = has.end;;) { for (var end = has.end;;) {
var next = hasImport(end.line + 1); var next = hasImport(end.line + 1);
if (next == null) break; if (next == null) break;
end = next.end; end = next.end;
} }
return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end}; return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end};
}); });
CodeMirror.importRangeFinder = CodeMirror.fold["import"]; // deprecated
CodeMirror.registerHelper("fold", "include", function(cm, start) { CodeMirror.registerHelper("fold", "include", function(cm, start) {
function hasInclude(line) { function hasInclude(line) {
@@ -80,14 +91,15 @@ CodeMirror.registerHelper("fold", "include", function(cm, start) {
if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8; if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
} }
var start = start.line, has = hasInclude(start); var startLine = start.line, has = hasInclude(startLine);
if (has == null || hasInclude(start - 1) != null) return null; if (has == null || hasInclude(startLine - 1) != null) return null;
for (var end = start;;) { for (var end = startLine;;) {
var next = hasInclude(end + 1); var next = hasInclude(end + 1);
if (next == null) break; if (next == null) break;
++end; ++end;
} }
return {from: CodeMirror.Pos(start, has + 1), return {from: CodeMirror.Pos(startLine, has + 1),
to: cm.clipPos(CodeMirror.Pos(end))}; to: cm.clipPos(CodeMirror.Pos(end))};
}); });
CodeMirror.includeRangeFinder = CodeMirror.fold.include; // deprecated
});

View File

@@ -1,3 +1,16 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.registerGlobalHelper("fold", "comment", function(mode) { CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
return mode.blockCommentStart && mode.blockCommentEnd; return mode.blockCommentStart && mode.blockCommentEnd;
}, function(cm, start) { }, function(cm, start) {
@@ -15,7 +28,9 @@ CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
continue; continue;
} }
if (pass == 1 && found < start.ch) return; if (pass == 1 && found < start.ch) return;
if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) { if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) &&
(found == 0 || lineText.slice(found - endToken.length, found) == endToken ||
!/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) {
startCh = found + startToken.length; startCh = found + startToken.length;
break; break;
} }
@@ -40,3 +55,5 @@ CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
return {from: CodeMirror.Pos(line, startCh), return {from: CodeMirror.Pos(line, startCh),
to: CodeMirror.Pos(end, endCh)}; to: CodeMirror.Pos(end, endCh)};
}); });
});

View File

@@ -1,11 +1,25 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
function doFold(cm, pos, options, force) { function doFold(cm, pos, options, force) {
var finder = options && (options.call ? options : options.rangeFinder); if (options && options.call) {
if (!finder) finder = CodeMirror.fold.auto; var finder = options;
options = null;
} else {
var finder = getOption(cm, options, "rangeFinder");
}
if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
var minSize = options && options.minFoldSize || 0; var minSize = getOption(cm, options, "minFoldSize");
function getRange(allowFolded) { function getRange(allowFolded) {
var range = finder(cm, pos); var range = finder(cm, pos);
@@ -22,17 +36,20 @@
} }
var range = getRange(true); var range = getRange(true);
if (options && options.scanUp) while (!range && pos.line > cm.firstLine()) { if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) {
pos = CodeMirror.Pos(pos.line - 1, 0); pos = CodeMirror.Pos(pos.line - 1, 0);
range = getRange(false); range = getRange(false);
} }
if (!range || range.cleared || force === "unfold") return; if (!range || range.cleared || force === "unfold") return;
var myWidget = makeWidget(options); var myWidget = makeWidget(cm, options);
CodeMirror.on(myWidget, "mousedown", function() { myRange.clear(); }); CodeMirror.on(myWidget, "mousedown", function(e) {
myRange.clear();
CodeMirror.e_preventDefault(e);
});
var myRange = cm.markText(range.from, range.to, { var myRange = cm.markText(range.from, range.to, {
replacedWith: myWidget, replacedWith: myWidget,
clearOnEnter: true, clearOnEnter: getOption(cm, options, "clearOnEnter"),
__isFold: true __isFold: true
}); });
myRange.on("clear", function(from, to) { myRange.on("clear", function(from, to) {
@@ -41,8 +58,8 @@
CodeMirror.signal(cm, "fold", cm, range.from, range.to); CodeMirror.signal(cm, "fold", cm, range.from, range.to);
} }
function makeWidget(options) { function makeWidget(cm, options) {
var widget = (options && options.widget) || "\u2194"; var widget = getOption(cm, options, "widget");
if (typeof widget == "string") { if (typeof widget == "string") {
var text = document.createTextNode(widget); var text = document.createTextNode(widget);
widget = document.createElement("span"); widget = document.createElement("span");
@@ -62,9 +79,33 @@
doFold(this, pos, options, force); doFold(this, pos, options, force);
}); });
CodeMirror.commands.fold = function(cm) { CodeMirror.defineExtension("isFolded", function(pos) {
var marks = this.findMarksAt(pos);
for (var i = 0; i < marks.length; ++i)
if (marks[i].__isFold) return true;
});
CodeMirror.commands.toggleFold = function(cm) {
cm.foldCode(cm.getCursor()); cm.foldCode(cm.getCursor());
}; };
CodeMirror.commands.fold = function(cm) {
cm.foldCode(cm.getCursor(), null, "fold");
};
CodeMirror.commands.unfold = function(cm) {
cm.foldCode(cm.getCursor(), null, "unfold");
};
CodeMirror.commands.foldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
cm.foldCode(CodeMirror.Pos(i, 0), null, "fold");
});
};
CodeMirror.commands.unfoldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold");
});
};
CodeMirror.registerHelper("fold", "combine", function() { CodeMirror.registerHelper("fold", "combine", function() {
var funcs = Array.prototype.slice.call(arguments, 0); var funcs = Array.prototype.slice.call(arguments, 0);
@@ -83,4 +124,27 @@
if (cur) return cur; if (cur) return cur;
} }
}); });
})();
var defaultOptions = {
rangeFinder: CodeMirror.fold.auto,
widget: "\u2194",
minFoldSize: 0,
scanUp: false,
clearOnEnter: true
};
CodeMirror.defineOption("foldOptions", null);
function getOption(cm, options, name) {
if (options && options[name] !== undefined)
return options[name];
var editorOptions = cm.options.foldOptions;
if (editorOptions && editorOptions[name] !== undefined)
return editorOptions[name];
return defaultOptions[name];
}
CodeMirror.defineExtension("foldOption", function(options, name) {
return getOption(this, options, name);
});
});

View File

@@ -10,7 +10,6 @@
} }
.CodeMirror-foldgutter-open, .CodeMirror-foldgutter-open,
.CodeMirror-foldgutter-folded { .CodeMirror-foldgutter-folded {
color: #555;
cursor: pointer; cursor: pointer;
} }
.CodeMirror-foldgutter-open:after { .CodeMirror-foldgutter-open:after {

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./foldcode"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./foldcode"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict"; "use strict";
CodeMirror.defineOption("foldGutter", false, function(cm, val, old) { CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
@@ -10,7 +20,7 @@
cm.off("viewportChange", onViewportChange); cm.off("viewportChange", onViewportChange);
cm.off("fold", onFold); cm.off("fold", onFold);
cm.off("unfold", onFold); cm.off("unfold", onFold);
cm.off("swapDoc", updateInViewport); cm.off("swapDoc", onChange);
} }
if (val) { if (val) {
cm.state.foldGutter = new State(parseOptions(val)); cm.state.foldGutter = new State(parseOptions(val));
@@ -20,7 +30,7 @@
cm.on("viewportChange", onViewportChange); cm.on("viewportChange", onViewportChange);
cm.on("fold", onFold); cm.on("fold", onFold);
cm.on("unfold", onFold); cm.on("unfold", onFold);
cm.on("swapDoc", updateInViewport); cm.on("swapDoc", onChange);
} }
}); });
@@ -40,15 +50,15 @@
} }
function isFolded(cm, line) { function isFolded(cm, line) {
var marks = cm.findMarksAt(Pos(line)); var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
for (var i = 0; i < marks.length; ++i) for (var i = 0; i < marks.length; ++i)
if (marks[i].__isFold && marks[i].find().from.line == line) return true; if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
} }
function marker(spec) { function marker(spec) {
if (typeof spec == "string") { if (typeof spec == "string") {
var elt = document.createElement("div"); var elt = document.createElement("div");
elt.className = spec; elt.className = spec + " CodeMirror-guttermarker-subtle";
return elt; return elt;
} else { } else {
return spec.cloneNode(true); return spec.cloneNode(true);
@@ -57,14 +67,16 @@
function updateFoldInfo(cm, from, to) { function updateFoldInfo(cm, from, to) {
var opts = cm.state.foldGutter.options, cur = from; var opts = cm.state.foldGutter.options, cur = from;
var minSize = cm.foldOption(opts, "minFoldSize");
var func = cm.foldOption(opts, "rangeFinder");
cm.eachLine(from, to, function(line) { cm.eachLine(from, to, function(line) {
var mark = null; var mark = null;
if (isFolded(cm, cur)) { if (isFolded(cm, cur)) {
mark = marker(opts.indicatorFolded); mark = marker(opts.indicatorFolded);
} else { } else {
var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto; var pos = Pos(cur, 0);
var range = func && func(cm, pos); var range = func && func(cm, pos);
if (range && range.from.line + 1 < range.to.line) if (range && range.to.line - range.from.line >= minSize)
mark = marker(opts.indicatorOpen); mark = marker(opts.indicatorOpen);
} }
cm.setGutterMarker(line, opts.gutter, mark); cm.setGutterMarker(line, opts.gutter, mark);
@@ -82,20 +94,28 @@
} }
function onGutterClick(cm, line, gutter) { function onGutterClick(cm, line, gutter) {
var opts = cm.state.foldGutter.options; var state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
if (gutter != opts.gutter) return; if (gutter != opts.gutter) return;
cm.foldCode(Pos(line, 0), opts.rangeFinder); var folded = isFolded(cm, line);
if (folded) folded.clear();
else cm.foldCode(Pos(line, 0), opts.rangeFinder);
} }
function onChange(cm) { function onChange(cm) {
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options; var state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
state.from = state.to = 0; state.from = state.to = 0;
clearTimeout(state.changeUpdate); clearTimeout(state.changeUpdate);
state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600); state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
} }
function onViewportChange(cm) { function onViewportChange(cm) {
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options; var state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
clearTimeout(state.changeUpdate); clearTimeout(state.changeUpdate);
state.changeUpdate = setTimeout(function() { state.changeUpdate = setTimeout(function() {
var vp = cm.getViewport(); var vp = cm.getViewport();
@@ -117,8 +137,10 @@
} }
function onFold(cm, from) { function onFold(cm, from) {
var state = cm.state.foldGutter, line = from.line; var state = cm.state.foldGutter;
if (!state) return;
var line = from.line;
if (line >= state.from && line < state.to) if (line >= state.from && line < state.to)
updateFoldInfo(cm, line, line + 1); updateFoldInfo(cm, line, line + 1);
} }
})(); });

View File

@@ -1,30 +1,48 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
function lineIndent(cm, lineNo) {
var text = cm.getLine(lineNo)
var spaceTo = text.search(/\S/)
if (spaceTo == -1 || /\bcomment\b/.test(cm.getTokenTypeAt(CodeMirror.Pos(lineNo, spaceTo + 1))))
return -1
return CodeMirror.countColumn(text, null, cm.getOption("tabSize"))
}
!
CodeMirror.registerHelper("fold", "indent", function(cm, start) { CodeMirror.registerHelper("fold", "indent", function(cm, start) {
var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); var myIndent = lineIndent(cm, start.line)
if (!/\S/.test(firstLine)) return; if (myIndent < 0) return
var getIndent = function(line) { var lastLineInFold = null
return CodeMirror.countColumn(line, null, tabSize);
};
var myIndent = getIndent(firstLine);
var lastLineInFold = null;
// Go through lines until we find a line that definitely doesn't belong in // Go through lines until we find a line that definitely doesn't belong in
// the block we're folding, or to the end. // the block we're folding, or to the end.
for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) { for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) {
var curLine = cm.getLine(i); var indent = lineIndent(cm, i)
var curIndent = getIndent(curLine); if (indent == -1) {
if (curIndent > myIndent) { } else if (indent > myIndent) {
// Lines with a greater indent are considered part of the block. // Lines with a greater indent are considered part of the block.
lastLineInFold = i; lastLineInFold = i;
} else if (!/\S/.test(curLine)) {
// Empty lines might be breaks within the block we're trying to fold.
} else { } else {
// A non-empty line at an indent equal to or less than ours marks the // If this line has non-space, non-comment content, and is
// start of another block. // indented less or equal to the start line, it is the start of
// another block.
break; break;
} }
} }
if (lastLineInFold) return { if (lastLineInFold) return {
from: CodeMirror.Pos(start.line, firstLine.length), from: CodeMirror.Pos(start.line, cm.getLine(start.line).length),
to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length) to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length)
}; };
}); });
CodeMirror.indentRangeFinder = CodeMirror.fold.indent; // deprecated
});

View File

@@ -0,0 +1,49 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.registerHelper("fold", "markdown", function(cm, start) {
var maxDepth = 100;
function isHeader(lineNo) {
var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0));
return tokentype && /\bheader\b/.test(tokentype);
}
function headerLevel(lineNo, line, nextLine) {
var match = line && line.match(/^#+/);
if (match && isHeader(lineNo)) return match[0].length;
match = nextLine && nextLine.match(/^[=\-]+\s*$/);
if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2;
return maxDepth;
}
var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1);
var level = headerLevel(start.line, firstLine, nextLine);
if (level === maxDepth) return undefined;
var lastLineNo = cm.lastLine();
var end = start.line, nextNextLine = cm.getLine(end + 2);
while (end < lastLineNo) {
if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break;
++end;
nextLine = nextNextLine;
nextNextLine = cm.getLine(end + 2);
}
return {
from: CodeMirror.Pos(start.line, firstLine.length),
to: CodeMirror.Pos(end, cm.getLine(end).length)
};
});
});

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
var Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos;
@@ -11,8 +21,8 @@
function Iter(cm, line, ch, range) { function Iter(cm, line, ch, range) {
this.line = line; this.ch = ch; this.line = line; this.ch = ch;
this.cm = cm; this.text = cm.getLine(line); this.cm = cm; this.text = cm.getLine(line);
this.min = range ? range.from : cm.firstLine(); this.min = range ? Math.max(range.from, cm.firstLine()) : cm.firstLine();
this.max = range ? range.to - 1 : cm.lastLine(); this.max = range ? Math.min(range.to - 1, cm.lastLine()) : cm.lastLine();
} }
function tagAt(iter, ch) { function tagAt(iter, ch) {
@@ -130,21 +140,20 @@
var openTag = toNextTag(iter), end; var openTag = toNextTag(iter), end;
if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return; if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return;
if (!openTag[1] && end != "selfClose") { if (!openTag[1] && end != "selfClose") {
var start = Pos(iter.line, iter.ch); var startPos = Pos(iter.line, iter.ch);
var close = findMatchingClose(iter, openTag[2]); var endPos = findMatchingClose(iter, openTag[2]);
return close && {from: start, to: close.from}; return endPos && {from: startPos, to: endPos.from};
} }
} }
}); });
CodeMirror.tagRangeFinder = CodeMirror.fold.xml; // deprecated
CodeMirror.findMatchingTag = function(cm, pos, range) { CodeMirror.findMatchingTag = function(cm, pos, range) {
var iter = new Iter(cm, pos.line, pos.ch, range); var iter = new Iter(cm, pos.line, pos.ch, range);
if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return; if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch); var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
var start = end && toTagStart(iter); var start = end && toTagStart(iter);
if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return; if (!end || !start || cmp(iter, pos) > 0) return;
var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]}; var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};
if (end == "selfClose") return {open: here, close: null, at: "open"};
if (start[1]) { // closing tag if (start[1]) { // closing tag
return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"}; return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};
@@ -154,10 +163,10 @@
} }
}; };
CodeMirror.findEnclosingTag = function(cm, pos, range) { CodeMirror.findEnclosingTag = function(cm, pos, range, tag) {
var iter = new Iter(cm, pos.line, pos.ch, range); var iter = new Iter(cm, pos.line, pos.ch, range);
for (;;) { for (;;) {
var open = findMatchingOpen(iter); var open = findMatchingOpen(iter, tag);
if (!open) break; if (!open) break;
var forward = new Iter(cm, pos.line, pos.ch, range); var forward = new Iter(cm, pos.line, pos.ch, range);
var close = findMatchingClose(forward, open.tag); var close = findMatchingClose(forward, open.tag);
@@ -168,6 +177,6 @@
// Used by addon/edit/closetag.js // Used by addon/edit/closetag.js
CodeMirror.scanForClosingTag = function(cm, pos, name, end) { CodeMirror.scanForClosingTag = function(cm, pos, name, end) {
var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null); var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null);
return !!findMatchingClose(iter, name); return findMatchingClose(iter, name);
}; };
})(); });

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
var WORD = /[\w$]+/, RANGE = 500; var WORD = /[\w$]+/, RANGE = 500;
@@ -7,16 +17,15 @@
var word = options && options.word || WORD; var word = options && options.word || WORD;
var range = options && options.range || RANGE; var range = options && options.range || RANGE;
var cur = editor.getCursor(), curLine = editor.getLine(cur.line); var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
var start = cur.ch, end = start; var end = cur.ch, start = end;
while (end < curLine.length && word.test(curLine.charAt(end))) ++end;
while (start && word.test(curLine.charAt(start - 1))) --start; while (start && word.test(curLine.charAt(start - 1))) --start;
var curWord = start != end && curLine.slice(start, end); var curWord = start != end && curLine.slice(start, end);
var list = [], seen = {}; var list = options && options.list || [], seen = {};
var re = new RegExp(word.source, "g"); var re = new RegExp(word.source, "g");
for (var dir = -1; dir <= 1; dir += 2) { for (var dir = -1; dir <= 1; dir += 2) {
var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
for (; line != end; line += dir) { for (; line != endLine; line += dir) {
var text = editor.getLine(line), m; var text = editor.getLine(line), m;
while (m = re.exec(text)) { while (m = re.exec(text)) {
if (line == cur.line && m[0] === curWord) continue; if (line == cur.line && m[0] === curWord) continue;
@@ -29,4 +38,4 @@
} }
return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
}); });
})(); });

View File

@@ -1,4 +1,14 @@
(function () { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../mode/css/css"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../mode/css/css"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict"; "use strict";
var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1, var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1,
@@ -10,7 +20,11 @@
var inner = CodeMirror.innerMode(cm.getMode(), token.state); var inner = CodeMirror.innerMode(cm.getMode(), token.state);
if (inner.mode.name != "css") return; if (inner.mode.name != "css") return;
var word = token.string, start = token.start, end = token.end; if (token.type == "keyword" && "!important".indexOf(token.string) == 0)
return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start),
to: CodeMirror.Pos(cur.line, token.end)};
var start = token.start, end = cur.ch, word = token.string.slice(0, end - start);
if (/[^\w$_-]/.test(word)) { if (/[^\w$_-]/.test(word)) {
word = ""; start = end = cur.ch; word = ""; start = end = cur.ch;
} }
@@ -24,7 +38,7 @@
result.push(name); result.push(name);
} }
var st = token.state.state; var st = inner.state.state;
if (st == "pseudo" || token.type == "variable-3") { if (st == "pseudo" || token.type == "variable-3") {
add(pseudoClasses); add(pseudoClasses);
} else if (st == "block" || st == "maybeprop") { } else if (st == "block" || st == "maybeprop") {
@@ -43,4 +57,4 @@
to: CodeMirror.Pos(cur.line, end) to: CodeMirror.Pos(cur.line, end)
}; };
}); });
})(); });

View File

@@ -1,4 +1,16 @@
(function () { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./xml-hint"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./xml-hint"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" "); var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" ");
var targets = ["_blank", "_self", "_top", "_parent"]; var targets = ["_blank", "_self", "_top", "_parent"];
var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"]; var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"];
@@ -332,6 +344,5 @@
if (options) for (var opt in options) local[opt] = options[opt]; if (options) for (var opt in options) local[opt] = options[opt];
return CodeMirror.hint.xml(cm, local); return CodeMirror.hint.xml(cm, local);
} }
CodeMirror.htmlHint = htmlHint; // deprecated
CodeMirror.registerHelper("hint", "html", htmlHint); CodeMirror.registerHelper("hint", "html", htmlHint);
})(); });

View File

@@ -1,4 +1,14 @@
(function () { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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 Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos;
function forEach(arr, f) { function forEach(arr, f) {
@@ -20,15 +30,20 @@
function scriptHint(editor, keywords, getToken, options) { function scriptHint(editor, keywords, getToken, options) {
// Find the token at the cursor // Find the token at the cursor
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; var cur = editor.getCursor(), token = getToken(editor, cur);
if (/\b(?:string|comment)\b/.test(token.type)) return; if (/\b(?:string|comment)\b/.test(token.type)) return;
token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; token.state = CodeMirror.innerMode(editor.getMode(), token.state).state;
// If it's not a 'word-style' token, ignore the token. // If it's not a 'word-style' token, ignore the token.
if (!/^[\w$_]*$/.test(token.string)) { if (!/^[\w$_]*$/.test(token.string)) {
token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, token = {start: cur.ch, end: cur.ch, string: "", state: token.state,
type: token.string == "." ? "property" : null}; type: token.string == "." ? "property" : null};
} else if (token.end > cur.ch) {
token.end = cur.ch;
token.string = token.string.slice(0, cur.ch - token.start);
} }
var tprop = token;
// If it is a property, find out what it is a property of. // If it is a property, find out what it is a property of.
while (tprop.type == "property") { while (tprop.type == "property") {
tprop = getToken(editor, Pos(cur.line, tprop.start)); tprop = getToken(editor, Pos(cur.line, tprop.start));
@@ -47,7 +62,6 @@
function (e, cur) {return e.getTokenAt(cur);}, function (e, cur) {return e.getTokenAt(cur);},
options); options);
}; };
CodeMirror.javascriptHint = javascriptHint; // deprecated
CodeMirror.registerHelper("hint", "javascript", javascriptHint); CodeMirror.registerHelper("hint", "javascript", javascriptHint);
function getCoffeeScriptToken(editor, cur) { function getCoffeeScriptToken(editor, cur) {
@@ -71,7 +85,6 @@
function coffeescriptHint(editor, options) { function coffeescriptHint(editor, options) {
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options); return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
} }
CodeMirror.coffeescriptHint = coffeescriptHint; // deprecated
CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint); CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " + var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
@@ -84,8 +97,17 @@
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " + var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" "); "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
function forAllProps(obj, callback) {
if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
for (var name in obj) callback(name)
} else {
for (var o = obj; o; o = Object.getPrototypeOf(o))
Object.getOwnPropertyNames(o).forEach(callback)
}
}
function getCompletions(token, context, keywords, options) { function getCompletions(token, context, keywords, options) {
var found = [], start = token.string; var found = [], start = token.string, global = options && options.globalScope || window;
function maybeAdd(str) { function maybeAdd(str) {
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str); if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
} }
@@ -93,7 +115,7 @@
if (typeof obj == "string") forEach(stringProps, maybeAdd); if (typeof obj == "string") forEach(stringProps, maybeAdd);
else if (obj instanceof Array) forEach(arrayProps, maybeAdd); else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
else if (obj instanceof Function) forEach(funcProps, maybeAdd); else if (obj instanceof Function) forEach(funcProps, maybeAdd);
for (var name in obj) maybeAdd(name); forAllProps(obj, maybeAdd)
} }
if (context && context.length) { if (context && context.length) {
@@ -103,29 +125,31 @@
if (obj.type && obj.type.indexOf("variable") === 0) { if (obj.type && obj.type.indexOf("variable") === 0) {
if (options && options.additionalContext) if (options && options.additionalContext)
base = options.additionalContext[obj.string]; base = options.additionalContext[obj.string];
base = base || window[obj.string]; if (!options || options.useGlobalScope !== false)
base = base || global[obj.string];
} else if (obj.type == "string") { } else if (obj.type == "string") {
base = ""; base = "";
} else if (obj.type == "atom") { } else if (obj.type == "atom") {
base = 1; base = 1;
} else if (obj.type == "function") { } else if (obj.type == "function") {
if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') && if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
(typeof window.jQuery == 'function')) (typeof global.jQuery == 'function'))
base = window.jQuery(); base = global.jQuery();
else if (window._ != null && (obj.string == '_') && (typeof window._ == 'function')) else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function'))
base = window._(); base = global._();
} }
while (base != null && context.length) while (base != null && context.length)
base = base[context.pop().string]; base = base[context.pop().string];
if (base != null) gatherCompletions(base); if (base != null) gatherCompletions(base);
} else { } else {
// If not, just look in the window object and any local scope // If not, just look in the global object and any local scope
// (reading into JS mode internals to get at the local and global variables) // (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 v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name); for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
gatherCompletions(window); if (!options || options.useGlobalScope !== false)
gatherCompletions(global);
forEach(keywords, maybeAdd); forEach(keywords, maybeAdd);
} }
return found; return found;
} }
})(); });

View File

@@ -1,121 +0,0 @@
(function () {
"use strict";
function forEach(arr, f) {
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
}
function arrayContains(arr, item) {
if (!Array.prototype.indexOf) {
var i = arr.length;
while (i--) {
if (arr[i] === item) {
return true;
}
}
return false;
}
return arr.indexOf(item) != -1;
}
function scriptHint(editor, _keywords, getToken) {
// Find the token at the cursor
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
// If it's not a 'word-style' token, ignore the token.
if (!/^[\w$_]*$/.test(token.string)) {
token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
className: token.string == ":" ? "pig-type" : null};
}
if (!context) var context = [];
context.push(tprop);
var completionList = getCompletions(token, context);
completionList = completionList.sort();
//prevent autocomplete for last word, instead show dropdown with one word
if(completionList.length == 1) {
completionList.push(" ");
}
return {list: completionList,
from: CodeMirror.Pos(cur.line, token.start),
to: CodeMirror.Pos(cur.line, token.end)};
}
function pigHint(editor) {
return scriptHint(editor, pigKeywordsU, function (e, cur) {return e.getTokenAt(cur);});
}
CodeMirror.pigHint = pigHint; // deprecated
CodeMirror.registerHelper("hint", "pig", pigHint);
var pigKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
+ "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
+ "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
+ "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE "
+ "NEQ MATCHES TRUE FALSE";
var pigKeywordsU = pigKeywords.split(" ");
var pigKeywordsL = pigKeywords.toLowerCase().split(" ");
var pigTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP";
var pigTypesU = pigTypes.split(" ");
var pigTypesL = pigTypes.toLowerCase().split(" ");
var pigBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL "
+ "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
+ "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
+ "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
+ "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
+ "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
+ "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA "
+ "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
+ "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
+ "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER";
var pigBuiltinsU = pigBuiltins.split(" ").join("() ").split(" ");
var pigBuiltinsL = pigBuiltins.toLowerCase().split(" ").join("() ").split(" ");
var pigBuiltinsC = ("BagSize BinStorage Bloom BuildBloom ConstantSize CubeDimensions DoubleAbs "
+ "DoubleAvg DoubleBase DoubleMax DoubleMin DoubleRound DoubleSum FloatAbs FloatAvg FloatMax "
+ "FloatMin FloatRound FloatSum GenericInvoker IntAbs IntAvg IntMax IntMin IntSum "
+ "InvokeForDouble InvokeForFloat InvokeForInt InvokeForLong InvokeForString Invoker "
+ "IsEmpty JsonLoader JsonMetadata JsonStorage LongAbs LongAvg LongMax LongMin LongSum MapSize "
+ "MonitoredUDF Nondeterministic OutputSchema PigStorage PigStreaming StringConcat StringMax "
+ "StringMin StringSize TextLoader TupleSize Utf8StorageConverter").split(" ").join("() ").split(" ");
function getCompletions(token, context) {
var found = [], start = token.string;
function maybeAdd(str) {
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
}
function gatherCompletions(obj) {
if(obj == ":") {
forEach(pigTypesL, maybeAdd);
}
else {
forEach(pigBuiltinsU, maybeAdd);
forEach(pigBuiltinsL, maybeAdd);
forEach(pigBuiltinsC, maybeAdd);
forEach(pigTypesU, maybeAdd);
forEach(pigTypesL, maybeAdd);
forEach(pigKeywordsU, maybeAdd);
forEach(pigKeywordsL, maybeAdd);
}
}
if (context) {
// If this is a property, see if it belongs to some object we can
// find in the current environment.
var obj = context.pop(), base;
if (obj.type == "variable")
base = obj.string;
else if(obj.type == "variable-3")
base = ":" + obj.string;
while (base != null && context.length)
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
}
return found;
}
})();

View File

@@ -1,91 +0,0 @@
(function () {
function forEach(arr, f) {
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
}
function arrayContains(arr, item) {
if (!Array.prototype.indexOf) {
var i = arr.length;
while (i--) {
if (arr[i] === item) {
return true;
}
}
return false;
}
return arr.indexOf(item) != -1;
}
function scriptHint(editor, _keywords, getToken) {
// Find the token at the cursor
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
// If it's not a 'word-style' token, ignore the token.
if (!/^[\w$_]*$/.test(token.string)) {
token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
className: token.string == ":" ? "python-type" : null};
}
if (!context) var context = [];
context.push(tprop);
var completionList = getCompletions(token, context);
completionList = completionList.sort();
return {list: completionList,
from: CodeMirror.Pos(cur.line, token.start),
to: CodeMirror.Pos(cur.line, token.end)};
}
function pythonHint(editor) {
return scriptHint(editor, pythonKeywordsU, function (e, cur) {return e.getTokenAt(cur);});
}
CodeMirror.pythonHint = pythonHint; // deprecated
CodeMirror.registerHelper("hint", "python", pythonHint);
var pythonKeywords = "and del from not while as elif global or with assert else if pass yield"
+ "break except import print class exec in raise continue finally is return def for lambda try";
var pythonKeywordsL = pythonKeywords.split(" ");
var pythonKeywordsU = pythonKeywords.toUpperCase().split(" ");
var pythonBuiltins = "abs divmod input open staticmethod all enumerate int ord str "
+ "any eval isinstance pow sum basestring execfile issubclass print super"
+ "bin file iter property tuple bool filter len range type"
+ "bytearray float list raw_input unichr callable format locals reduce unicode"
+ "chr frozenset long reload vars classmethod getattr map repr xrange"
+ "cmp globals max reversed zip compile hasattr memoryview round __import__"
+ "complex hash min set apply delattr help next setattr buffer"
+ "dict hex object slice coerce dir id oct sorted intern ";
var pythonBuiltinsL = pythonBuiltins.split(" ").join("() ").split(" ");
var pythonBuiltinsU = pythonBuiltins.toUpperCase().split(" ").join("() ").split(" ");
function getCompletions(token, context) {
var found = [], start = token.string;
function maybeAdd(str) {
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
}
function gatherCompletions(_obj) {
forEach(pythonBuiltinsL, maybeAdd);
forEach(pythonBuiltinsU, maybeAdd);
forEach(pythonKeywordsL, maybeAdd);
forEach(pythonKeywordsU, maybeAdd);
}
if (context) {
// If this is a property, see if it belongs to some object we can
// find in the current environment.
var obj = context.pop(), base;
if (obj.type == "variable")
base = obj.string;
else if(obj.type == "variable-3")
base = ":" + obj.string;
while (base != null && context.length)
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
}
return found;
}
})();

View File

@@ -25,14 +25,12 @@
margin: 0; margin: 0;
padding: 0 4px; padding: 0 4px;
border-radius: 2px; border-radius: 2px;
max-width: 19em;
overflow: hidden;
white-space: pre; white-space: pre;
color: black; color: black;
cursor: pointer; cursor: pointer;
} }
.CodeMirror-hint-active { li.CodeMirror-hint-active {
background: #08f; background: #08f;
color: white; color: white;
} }

View File

@@ -1,41 +1,78 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
var HINT_ELEMENT_CLASS = "CodeMirror-hint"; var HINT_ELEMENT_CLASS = "CodeMirror-hint";
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
// This is the old interface, kept around for now to stay
// backwards-compatible.
CodeMirror.showHint = function(cm, getHints, options) { CodeMirror.showHint = function(cm, getHints, options) {
// We want a single cursor position. if (!getHints) return cm.showHint(options);
if (cm.somethingSelected()) return; if (options && options.async) getHints.async = true;
if (getHints == null) { var newOpts = {hint: getHints};
if (options && options.async) return; if (options) for (var prop in options) newOpts[prop] = options[prop];
else getHints = CodeMirror.hint.auto; return cm.showHint(newOpts);
}
if (cm.state.completionActive) cm.state.completionActive.close();
var completion = cm.state.completionActive = new Completion(cm, getHints, options || {});
CodeMirror.signal(cm, "startCompletion", cm);
if (completion.options.async)
getHints(cm, function(hints) { completion.showHints(hints); }, completion.options);
else
return completion.showHints(getHints(cm, completion.options));
}; };
function Completion(cm, getHints, options) { CodeMirror.defineExtension("showHint", function(options) {
options = parseOptions(this, this.getCursor("start"), options);
var selections = this.listSelections()
if (selections.length > 1) return;
// By default, don't allow completion when something is selected.
// A hint function can have a `supportsSelection` property to
// indicate that it can handle selections.
if (this.somethingSelected()) {
if (!options.hint.supportsSelection) return;
// Don't try with cross-line selections
for (var i = 0; i < selections.length; i++)
if (selections[i].head.line != selections[i].anchor.line) return;
}
if (this.state.completionActive) this.state.completionActive.close();
var completion = this.state.completionActive = new Completion(this, options);
if (!completion.options.hint) return;
CodeMirror.signal(this, "startCompletion", this);
completion.update(true);
});
function Completion(cm, options) {
this.cm = cm; this.cm = cm;
this.getHints = getHints;
this.options = options; this.options = options;
this.widget = this.onClose = null; this.widget = null;
this.debounce = 0;
this.tick = 0;
this.startPos = this.cm.getCursor("start");
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
var self = this;
cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
} }
var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
return setTimeout(fn, 1000/60);
};
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
Completion.prototype = { Completion.prototype = {
close: function() { close: function() {
if (!this.active()) return; if (!this.active()) return;
this.cm.state.completionActive = null; this.cm.state.completionActive = null;
this.tick = null;
this.cm.off("cursorActivity", this.activityFunc);
if (this.widget && this.data) CodeMirror.signal(this.data, "close");
if (this.widget) this.widget.close(); if (this.widget) this.widget.close();
if (this.onClose) this.onClose();
CodeMirror.signal(this.cm, "endCompletion", this.cm); CodeMirror.signal(this.cm, "endCompletion", this.cm);
}, },
@@ -46,86 +83,81 @@
pick: function(data, i) { pick: function(data, i) {
var completion = data.list[i]; var completion = data.list[i];
if (completion.hint) completion.hint(this.cm, data, completion); if (completion.hint) completion.hint(this.cm, data, completion);
else this.cm.replaceRange(getText(completion), data.from, data.to); else this.cm.replaceRange(getText(completion), completion.from || data.from,
completion.to || data.to, "complete");
CodeMirror.signal(data, "pick", completion); CodeMirror.signal(data, "pick", completion);
this.close(); this.close();
}, },
showHints: function(data) { cursorActivity: function() {
if (!data || !data.list.length || !this.active()) return this.close(); if (this.debounce) {
cancelAnimationFrame(this.debounce);
this.debounce = 0;
}
if (this.options.completeSingle != false && data.list.length == 1) var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
this.pick(data, 0); if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
else pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
this.showWidget(data); (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close();
} else {
var self = this;
this.debounce = requestAnimationFrame(function() {self.update();});
if (this.widget) this.widget.disable();
}
}, },
showWidget: function(data) { update: function(first) {
this.widget = new Widget(this, data); if (this.tick == null) return
CodeMirror.signal(data, "shown"); var self = this, myTick = ++this.tick
fetchHints(this.options.hint, this.cm, this.options, function(data) {
if (self.tick == myTick) self.finishUpdate(data, first)
})
},
var debounce = 0, completion = this, finished; finishUpdate: function(data, first) {
var closeOn = this.options.closeCharacters || /[\s()\[\]{};:>,]/; if (this.data) CodeMirror.signal(this.data, "update");
var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;
var requestAnimationFrame = window.requestAnimationFrame || function(fn) { var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
return setTimeout(fn, 1000/60); if (this.widget) this.widget.close();
};
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
function done() { if (data && this.data && isNewCompletion(this.data, data)) return;
if (finished) return; this.data = data;
finished = true;
completion.close();
completion.cm.off("cursorActivity", activity);
if (data) CodeMirror.signal(data, "close");
}
function update() { if (data && data.list.length) {
if (finished) return; if (picked && data.list.length == 1) {
CodeMirror.signal(data, "update"); this.pick(data, 0);
if (completion.options.async)
completion.getHints(completion.cm, finishUpdate, completion.options);
else
finishUpdate(completion.getHints(completion.cm, completion.options));
}
function finishUpdate(data_) {
data = data_;
if (finished) return;
if (!data || !data.list.length) return done();
completion.widget = new Widget(completion, data);
}
function clearDebounce() {
if (debounce) {
cancelAnimationFrame(debounce);
debounce = 0;
}
}
function activity() {
clearDebounce();
var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line);
if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch ||
pos.ch < startPos.ch || completion.cm.somethingSelected() ||
(pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {
completion.close();
} else { } else {
debounce = requestAnimationFrame(update); this.widget = new Widget(this, data);
if (completion.widget) completion.widget.close(); CodeMirror.signal(data, "shown");
} }
} }
this.cm.on("cursorActivity", activity);
this.onClose = done;
} }
}; };
function isNewCompletion(old, nw) {
var moved = CodeMirror.cmpPos(nw.from, old.from)
return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch
}
function parseOptions(cm, pos, options) {
var editor = cm.options.hintOptions;
var out = {};
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
if (editor) for (var prop in editor)
if (editor[prop] !== undefined) out[prop] = editor[prop];
if (options) for (var prop in options)
if (options[prop] !== undefined) out[prop] = options[prop];
if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
return out;
}
function getText(completion) { function getText(completion) {
if (typeof completion == "string") return completion; if (typeof completion == "string") return completion;
else return completion.text; else return completion.text;
} }
function buildKeyMap(options, handle) { function buildKeyMap(completion, handle) {
var baseMap = { var baseMap = {
Up: function() {handle.moveFocus(-1);}, Up: function() {handle.moveFocus(-1);},
Down: function() {handle.moveFocus(1);}, Down: function() {handle.moveFocus(1);},
@@ -137,7 +169,8 @@
Tab: handle.pick, Tab: handle.pick,
Esc: handle.close Esc: handle.close
}; };
var ourMap = options.customKeys ? {} : baseMap; var custom = completion.options.customKeys;
var ourMap = custom ? {} : baseMap;
function addBinding(key, val) { function addBinding(key, val) {
var bound; var bound;
if (typeof val != "string") if (typeof val != "string")
@@ -149,12 +182,13 @@
bound = val; bound = val;
ourMap[key] = bound; ourMap[key] = bound;
} }
if (options.customKeys) if (custom)
for (var key in options.customKeys) if (options.customKeys.hasOwnProperty(key)) for (var key in custom) if (custom.hasOwnProperty(key))
addBinding(key, options.customKeys[key]); addBinding(key, custom[key]);
if (options.extraKeys) var extra = completion.options.extraKeys;
for (var key in options.extraKeys) if (options.extraKeys.hasOwnProperty(key)) if (extra)
addBinding(key, options.extraKeys[key]); for (var key in extra) if (extra.hasOwnProperty(key))
addBinding(key, extra[key]);
return ourMap; return ourMap;
} }
@@ -168,11 +202,12 @@
function Widget(completion, data) { function Widget(completion, data) {
this.completion = completion; this.completion = completion;
this.data = data; this.data = data;
var widget = this, cm = completion.cm, options = completion.options; this.picked = false;
var widget = this, cm = completion.cm;
var hints = this.hints = document.createElement("ul"); var hints = this.hints = document.createElement("ul");
hints.className = "CodeMirror-hints"; hints.className = "CodeMirror-hints";
this.selectedHint = options.getDefaultSelection ? options.getDefaultSelection(cm,options,data) : 0; this.selectedHint = data.selectedHint || 0;
var completions = data.list; var completions = data.list;
for (var i = 0; i < completions.length; ++i) { for (var i = 0; i < completions.length; ++i) {
@@ -185,16 +220,35 @@
elt.hintId = i; elt.hintId = i;
} }
var pos = cm.cursorCoords(options.alignWithWord !== false ? data.from : null); var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
var left = pos.left, top = pos.bottom, below = true; var left = pos.left, top = pos.bottom, below = true;
hints.style.left = left + "px"; hints.style.left = left + "px";
hints.style.top = top + "px"; hints.style.top = top + "px";
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
(options.container || document.body).appendChild(hints); (completion.options.container || document.body).appendChild(hints);
var box = hints.getBoundingClientRect(); var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
var overlapX = box.right - winW, overlapY = box.bottom - winH; var scrolls = hints.scrollHeight > hints.clientHeight + 1
var startScroll = cm.getScrollInfo();
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";
below = false;
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
hints.style.top = (top = pos.bottom - box.top) + "px";
var cursor = cm.getCursor();
if (data.from.ch != cursor.ch) {
pos = cm.cursorCoords(cursor);
hints.style.left = (left = pos.left) + "px";
box = hints.getBoundingClientRect();
}
}
}
var overlapX = box.right - winW;
if (overlapX > 0) { if (overlapX > 0) {
if (box.right - box.left > winW) { if (box.right - box.left > winW) {
hints.style.width = (winW - 5) + "px"; hints.style.width = (winW - 5) + "px";
@@ -202,34 +256,25 @@
} }
hints.style.left = (left = pos.left - overlapX) + "px"; hints.style.left = (left = pos.left - overlapX) + "px";
} }
if (overlapY > 0) { if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
var height = box.bottom - box.top; node.style.paddingRight = cm.display.nativeBarWidth + "px"
if (box.top - (pos.bottom - pos.top) - height > 0) {
overlapY = height + (pos.bottom - pos.top);
below = false;
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
overlapY -= height - winH;
}
hints.style.top = (top = pos.bottom - overlapY) + "px";
}
cm.addKeyMap(this.keyMap = buildKeyMap(options, { cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
setFocus: function(n) { widget.changeActive(n); }, setFocus: function(n) { widget.changeActive(n); },
menuSize: function() { return widget.screenAmount(); }, menuSize: function() { return widget.screenAmount(); },
length: completions.length, length: completions.length,
close: function() { completion.close(); }, close: function() { completion.close(); },
pick: function() { widget.pick(); } pick: function() { widget.pick(); },
data: data
})); }));
if (options.closeOnUnfocus !== false) { if (completion.options.closeOnUnfocus) {
var closingOnBlur; var closingOnBlur;
cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); }); cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); }); cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
} }
var startScroll = cm.getScrollInfo();
cm.on("scroll", this.onScroll = function() { cm.on("scroll", this.onScroll = function() {
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
var newTop = top + startScroll.top - curScroll.top; var newTop = top + startScroll.top - curScroll.top;
@@ -249,7 +294,7 @@
var t = getHintElement(hints, e.target || e.srcElement); var t = getHintElement(hints, e.target || e.srcElement);
if (t && t.hintId != null) { if (t && t.hintId != null) {
widget.changeActive(t.hintId); widget.changeActive(t.hintId);
if (options.completeOnSingleClick) widget.pick(); if (completion.options.completeOnSingleClick) widget.pick();
} }
}); });
@@ -269,13 +314,20 @@
this.completion.cm.removeKeyMap(this.keyMap); this.completion.cm.removeKeyMap(this.keyMap);
var cm = this.completion.cm; var cm = this.completion.cm;
if (this.completion.options.closeOnUnfocus !== false) { if (this.completion.options.closeOnUnfocus) {
cm.off("blur", this.onBlur); cm.off("blur", this.onBlur);
cm.off("focus", this.onFocus); cm.off("focus", this.onFocus);
} }
cm.off("scroll", this.onScroll); cm.off("scroll", this.onScroll);
}, },
disable: function() {
this.completion.cm.removeKeyMap(this.keyMap);
var widget = this;
this.keyMap = {Enter: function() { widget.picked = true; }};
this.completion.cm.addKeyMap(this.keyMap);
},
pick: function() { pick: function() {
this.completion.pick(this.data, this.selectedHint); this.completion.pick(this.data, this.selectedHint);
}, },
@@ -302,34 +354,85 @@
} }
}; };
CodeMirror.registerHelper("hint", "auto", function(cm, options) { function applicableHelpers(cm, helpers) {
var helpers = cm.getHelpers(cm.getCursor(), "hint"); if (!cm.somethingSelected()) return helpers
if (helpers.length) { var result = []
for (var i = 0; i < helpers.length; i++) { for (var i = 0; i < helpers.length; i++)
var cur = helpers[i](cm, options); if (helpers[i].supportsSelection) result.push(helpers[i])
if (cur && cur.list.length) return cur; return result
} }
function fetchHints(hint, cm, options, callback) {
if (hint.async) {
hint(cm, callback, options)
} else { } else {
var words = cm.getHelper(cm.getCursor(), "hintWords"); var result = hint(cm, options)
if (words) return CodeMirror.hint.fromList(cm, {words: words}); if (result && result.then) result.then(callback)
else callback(result)
} }
}
function resolveAutoHints(cm, pos) {
var helpers = cm.getHelpers(pos, "hint"), words
if (helpers.length) {
var resolved = function(cm, callback, options) {
var app = applicableHelpers(cm, helpers);
function run(i) {
if (i == app.length) return callback(null)
fetchHints(app[i], cm, options, function(result) {
if (result && result.list.length > 0) callback(result)
else run(i + 1)
})
}
run(0)
}
resolved.async = true
resolved.supportsSelection = true
return resolved
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
} else if (CodeMirror.hint.anyword) {
return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
} else {
return function() {}
}
}
CodeMirror.registerHelper("hint", "auto", {
resolve: resolveAutoHints
}); });
CodeMirror.registerHelper("hint", "fromList", function(cm, options) { CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur); var cur = cm.getCursor(), token = cm.getTokenAt(cur);
var to = CodeMirror.Pos(cur.line, token.end);
if (token.string && /\w/.test(token.string[token.string.length - 1])) {
var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
} else {
var term = "", from = to;
}
var found = []; var found = [];
for (var i = 0; i < options.words.length; i++) { for (var i = 0; i < options.words.length; i++) {
var word = options.words[i]; var word = options.words[i];
if (word.slice(0, token.string.length) == token.string) if (word.slice(0, term.length) == term)
found.push(word); found.push(word);
} }
if (found.length) return { if (found.length) return {list: found, from: from, to: to};
list: found,
from: CodeMirror.Pos(cur.line, token.start),
to: CodeMirror.Pos(cur.line, token.end)
};
}); });
CodeMirror.commands.autocomplete = CodeMirror.showHint; CodeMirror.commands.autocomplete = CodeMirror.showHint;
})();
var defaultOptions = {
hint: CodeMirror.hint.auto,
completeSingle: true,
alignWithWord: true,
closeCharacters: /[\s()\[\]{};:>,]/,
closeOnUnfocus: true,
completeOnSingleClick: true,
container: null,
customKeys: null,
extraKeys: null
};
CodeMirror.defineOption("hintOptions", null);
});

View File

@@ -1,72 +1,198 @@
(function () { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict"; "use strict";
var tables; var tables;
var defaultTable;
var keywords; var keywords;
var identifierQuote;
var CONS = { var CONS = {
QUERY_DIV: ";", QUERY_DIV: ";",
ALIAS_KEYWORD: "AS" ALIAS_KEYWORD: "AS"
}; };
var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }
function getKeywords(editor) { function getKeywords(editor) {
var mode = editor.doc.modeOption; var mode = editor.doc.modeOption;
if(mode === "sql") mode = "text/x-sql"; if (mode === "sql") mode = "text/x-sql";
return CodeMirror.resolveMode(mode).keywords; return CodeMirror.resolveMode(mode).keywords;
} }
function getIdentifierQuote(editor) {
var mode = editor.doc.modeOption;
if (mode === "sql") mode = "text/x-sql";
return CodeMirror.resolveMode(mode).identifierQuote || "`";
}
function getText(item) {
return typeof item == "string" ? item : item.text;
}
function wrapTable(name, value) {
if (isArray(value)) value = {columns: value}
if (!value.text) value.text = name
return value
}
function parseTables(input) {
var result = {}
if (isArray(input)) {
for (var i = input.length - 1; i >= 0; i--) {
var item = input[i]
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
}
} else if (input) {
for (var name in input)
result[name.toUpperCase()] = wrapTable(name, input[name])
}
return result
}
function getTable(name) {
return tables[name.toUpperCase()]
}
function shallowClone(object) {
var result = {};
for (var key in object) if (object.hasOwnProperty(key))
result[key] = object[key];
return result;
}
function match(string, word) { function match(string, word) {
var len = string.length; var len = string.length;
var sub = word.substr(0, len); var sub = getText(word).substr(0, len);
return string.toUpperCase() === sub.toUpperCase(); return string.toUpperCase() === sub.toUpperCase();
} }
function addMatches(result, search, wordlist, formatter) { function addMatches(result, search, wordlist, formatter) {
for(var word in wordlist) { if (isArray(wordlist)) {
if(!wordlist.hasOwnProperty(word)) continue; for (var i = 0; i < wordlist.length; i++)
if(Array.isArray(wordlist)) { if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
word = wordlist[word]; } else {
} for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
if(match(search, word)) { var val = wordlist[word]
result.push(formatter(word)); if (!val || val === true)
val = word
else
val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
if (match(search, val)) result.push(formatter(val))
} }
} }
} }
function columnCompletion(result, editor) { function cleanName(name) {
var cur = editor.getCursor(); // Get rid name from identifierQuote and preceding dot(.)
var token = editor.getTokenAt(cur); if (name.charAt(0) == ".") {
var string = token.string.substr(1); name = name.substr(1);
var prevCur = CodeMirror.Pos(cur.line, token.start); }
var table = editor.getTokenAt(prevCur).string; // replace doublicated identifierQuotes with single identifierQuotes
if( !tables.hasOwnProperty( table ) ){ // and remove single identifierQuotes
var nameParts = name.split(identifierQuote+identifierQuote);
for (var i = 0; i < nameParts.length; i++)
nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote,"g"), "");
return nameParts.join(identifierQuote);
}
function insertIdentifierQuotes(name) {
var nameParts = getText(name).split(".");
for (var i = 0; i < nameParts.length; i++)
nameParts[i] = identifierQuote +
// doublicate identifierQuotes
nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
identifierQuote;
var escaped = nameParts.join(".");
if (typeof name == "string") return escaped;
name = shallowClone(name);
name.text = escaped;
return name;
}
function nameCompletion(cur, token, result, editor) {
// Try to complete table, column names and return start position of completion
var useIdentifierQuotes = false;
var nameParts = [];
var start = token.start;
var cont = true;
while (cont) {
cont = (token.string.charAt(0) == ".");
useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);
start = token.start;
nameParts.unshift(cleanName(token.string));
token = editor.getTokenAt(Pos(cur.line, token.start));
if (token.string == ".") {
cont = true;
token = editor.getTokenAt(Pos(cur.line, token.start));
}
}
// Try to complete table names
var string = nameParts.join(".");
addMatches(result, string, tables, function(w) {
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
// Try to complete columns from defaultTable
addMatches(result, string, defaultTable, function(w) {
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
// Try to complete columns
string = nameParts.pop();
var table = nameParts.join(".");
var alias = false;
var aliasTable = table;
// Check if table is available. If not, find table by Alias
if (!getTable(table)) {
var oldTable = table;
table = findTableByAlias(table, editor); table = findTableByAlias(table, editor);
if (table !== oldTable) alias = true;
} }
var columns = tables[table];
if(!columns) { var columns = getTable(table);
return; if (columns && columns.columns)
columns = columns.columns;
if (columns) {
addMatches(result, string, columns, function(w) {
var tableInsert = table;
if (alias == true) tableInsert = aliasTable;
if (typeof w == "string") {
w = tableInsert + "." + w;
} else {
w = shallowClone(w);
w.text = tableInsert + "." + w.text;
}
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
} }
addMatches(result, string, columns,
function(w) {return "." + w;}); return start;
} }
function eachWord(lineText, f) { function eachWord(lineText, f) {
if( !lineText ){return;} if (!lineText) return;
var excepted = /[,;]/g; var excepted = /[,;]/g;
var words = lineText.split( " " ); var words = lineText.split(" ");
for( var i = 0; i < words.length; i++ ){ for (var i = 0; i < words.length; i++) {
f( words[i]?words[i].replace( excepted, '' ) : '' ); f(words[i]?words[i].replace(excepted, '') : '');
} }
} }
function convertCurToNumber( cur ){
// max characters of a line is 999,999.
return cur.line + cur.ch / Math.pow( 10, 6 );
}
function convertNumberToCur( num ){
return CodeMirror.Pos(Math.floor( num ), +num.toString().split( '.' ).pop());
}
function findTableByAlias(alias, editor) { function findTableByAlias(alias, editor) {
var doc = editor.doc; var doc = editor.doc;
var fullQuery = doc.getValue(); var fullQuery = doc.getValue();
@@ -75,72 +201,87 @@
var table = ""; var table = "";
var separator = []; var separator = [];
var validRange = { var validRange = {
start: CodeMirror.Pos( 0, 0 ), start: Pos(0, 0),
end: CodeMirror.Pos( editor.lastLine(), editor.getLineHandle( editor.lastLine() ).length ) end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
}; };
//add separator //add separator
var indexOfSeparator = fullQuery.indexOf( CONS.QUERY_DIV ); var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
while( indexOfSeparator != -1 ){ while(indexOfSeparator != -1) {
separator.push( doc.posFromIndex(indexOfSeparator)); separator.push(doc.posFromIndex(indexOfSeparator));
indexOfSeparator = fullQuery.indexOf( CONS.QUERY_DIV, indexOfSeparator+1); indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
} }
separator.unshift( CodeMirror.Pos( 0, 0 ) ); separator.unshift(Pos(0, 0));
separator.push( CodeMirror.Pos( editor.lastLine(), editor.getLineHandle( editor.lastLine() ).text.length ) ); separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
//find valieRange //find valid range
var prevItem = 0; var prevItem = null;
var current = convertCurToNumber( editor.getCursor() ); var current = editor.getCursor()
for( var i=0; i< separator.length; i++){ for (var i = 0; i < separator.length; i++) {
var _v = convertCurToNumber( separator[i] ); if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
if( current > prevItem && current <= _v ){ validRange = {start: prevItem, end: separator[i]};
validRange = { start: convertNumberToCur( prevItem ), end: convertNumberToCur( _v ) };
break; break;
} }
prevItem = _v; prevItem = separator[i];
} }
var query = doc.getRange(validRange.start, validRange.end, false); var query = doc.getRange(validRange.start, validRange.end, false);
for(var i=0; i < query.length; i++){ for (var i = 0; i < query.length; i++) {
var lineText = query[i]; var lineText = query[i];
eachWord( lineText, function( word ){ eachWord(lineText, function(word) {
var wordUpperCase = word.toUpperCase(); var wordUpperCase = word.toUpperCase();
if( wordUpperCase === aliasUpperCase && tables.hasOwnProperty( previousWord ) ){ if (wordUpperCase === aliasUpperCase && getTable(previousWord))
table = previousWord; table = previousWord;
} if (wordUpperCase !== CONS.ALIAS_KEYWORD)
if( wordUpperCase !== CONS.ALIAS_KEYWORD ){
previousWord = word; previousWord = word;
}
}); });
if( table ){ break; } if (table) break;
} }
return table; return table;
} }
function sqlHint(editor, options) { CodeMirror.registerHelper("hint", "sql", function(editor, options) {
tables = (options && options.tables) || {}; tables = parseTables(options && options.tables)
keywords = keywords || getKeywords(editor); var defaultTableName = options && options.defaultTable;
var disableKeywords = options && options.disableKeywords;
defaultTable = defaultTableName && getTable(defaultTableName);
keywords = getKeywords(editor);
identifierQuote = getIdentifierQuote(editor);
if (defaultTableName && !defaultTable)
defaultTable = findTableByAlias(defaultTableName, editor);
defaultTable = defaultTable || [];
if (defaultTable.columns)
defaultTable = defaultTable.columns;
var cur = editor.getCursor(); var cur = editor.getCursor();
var token = editor.getTokenAt(cur);
var result = []; var result = [];
var search = token.string.trim(); var token = editor.getTokenAt(cur), start, end, search;
if (token.end > cur.ch) {
addMatches(result, search, keywords, token.end = cur.ch;
function(w) {return w.toUpperCase();}); token.string = token.string.slice(0, cur.ch - token.start);
addMatches(result, search, tables,
function(w) {return w;});
if(search.lastIndexOf('.') === 0) {
columnCompletion(result, editor);
} }
return { if (token.string.match(/^[.`"\w@]\w*$/)) {
list: result, search = token.string;
from: CodeMirror.Pos(cur.line, token.start), start = token.start;
to: CodeMirror.Pos(cur.line, token.end) end = token.end;
}; } else {
} start = end = cur.ch;
CodeMirror.registerHelper("hint", "sql", sqlHint); search = "";
})(); }
if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
start = nameCompletion(cur, token, result, editor);
} else {
addMatches(result, search, tables, function(w) {return w;});
addMatches(result, search, defaultTable, function(w) {return w;});
if (!disableKeywords)
addMatches(result, search, keywords, function(w) {return w.toUpperCase();});
}
return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
});
});

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
var Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos;
@@ -8,30 +18,55 @@
var quote = (options && options.quoteChar) || '"'; var quote = (options && options.quoteChar) || '"';
if (!tags) return; if (!tags) return;
var cur = cm.getCursor(), token = cm.getTokenAt(cur); var cur = cm.getCursor(), token = cm.getTokenAt(cur);
if (token.end > cur.ch) {
token.end = cur.ch;
token.string = token.string.slice(0, cur.ch - token.start);
}
var inner = CodeMirror.innerMode(cm.getMode(), token.state); var inner = CodeMirror.innerMode(cm.getMode(), token.state);
if (inner.mode.name != "xml") return; if (inner.mode.name != "xml") return;
var result = [], replaceToken = false, prefix; var result = [], replaceToken = false, prefix;
var isTag = token.string.charAt(0) == "<"; var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string);
if (!inner.state.tagName || isTag) { // Tag completion var tagName = tag && /^\w/.test(token.string), tagStart;
if (isTag) {
prefix = token.string.slice(1); if (tagName) {
replaceToken = true; var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start);
} var tagType = /<\/$/.test(before) ? "close" : /<$/.test(before) ? "open" : null;
if (tagType) tagStart = token.start - (tagType == "close" ? 2 : 1);
} else if (tag && token.string == "<") {
tagType = "open";
} else if (tag && token.string == "</") {
tagType = "close";
}
if (!tag && !inner.state.tagName || tagType) {
if (tagName)
prefix = token.string;
replaceToken = tagType;
var cx = inner.state.context, curTag = cx && tags[cx.tagName]; var cx = inner.state.context, curTag = cx && tags[cx.tagName];
var childList = cx ? curTag && curTag.children : tags["!top"]; var childList = cx ? curTag && curTag.children : tags["!top"];
if (childList) { if (childList && tagType != "close") {
for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0) for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0)
result.push("<" + childList[i]); result.push("<" + childList[i]);
} else { } else if (tagType != "close") {
for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.lastIndexOf(prefix, 0) == 0)) for (var name in tags)
result.push("<" + name); if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
result.push("<" + name);
} }
if (cx && (!prefix || ("/" + cx.tagName).lastIndexOf(prefix, 0) == 0)) if (cx && (!prefix || tagType == "close" && cx.tagName.lastIndexOf(prefix, 0) == 0))
result.push("</" + cx.tagName + ">"); result.push("</" + cx.tagName + ">");
} else { } else {
// Attribute completion // Attribute completion
var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs; var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs;
if (!attrs) return; var globalAttrs = tags["!attrs"];
if (!attrs && !globalAttrs) return;
if (!attrs) {
attrs = globalAttrs;
} else if (globalAttrs) { // Combine tag-local and global attributes
var set = {};
for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm];
for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm];
attrs = set;
}
if (token.type == "string" || token.string == "=") { // A value if (token.type == "string" || token.string == "=") { // A value
var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)), var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)),
Pos(cur.line, token.type == "string" ? token.start : token.end)); Pos(cur.line, token.type == "string" ? token.start : token.end));
@@ -40,9 +75,16 @@
if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget
if (token.type == "string") { if (token.type == "string") {
prefix = token.string; prefix = token.string;
var n = 0;
if (/['"]/.test(token.string.charAt(0))) { if (/['"]/.test(token.string.charAt(0))) {
quote = token.string.charAt(0); quote = token.string.charAt(0);
prefix = token.string.slice(1); prefix = token.string.slice(1);
n++;
}
var len = token.string.length;
if (/['"]/.test(token.string.charAt(len - 1))) {
quote = token.string.charAt(len - 1);
prefix = token.string.substr(n, len - 2);
} }
replaceToken = true; replaceToken = true;
} }
@@ -59,11 +101,10 @@
} }
return { return {
list: result, list: result,
from: replaceToken ? Pos(cur.line, token.start) : cur, from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
to: replaceToken ? Pos(cur.line, token.end) : cur to: replaceToken ? Pos(cur.line, token.end) : cur
}; };
} }
CodeMirror.xmlHint = getHints; // deprecated
CodeMirror.registerHelper("hint", "xml", getHints); CodeMirror.registerHelper("hint", "xml", getHints);
})(); });

View File

@@ -1,7 +1,20 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js // Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js
// declare global: coffeelint // declare global: coffeelint
(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) {
"use strict";
CodeMirror.registerHelper("lint", "coffeescript", function(text) { CodeMirror.registerHelper("lint", "coffeescript", function(text) {
var found = []; var found = [];
var parseError = function(err) { var parseError = function(err) {
@@ -24,4 +37,5 @@ CodeMirror.registerHelper("lint", "coffeescript", function(text) {
} }
return found; return found;
}); });
CodeMirror.coffeeValidator = CodeMirror.lint.coffeescript; // deprecated
});

View File

@@ -1,9 +1,23 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Depends on csslint.js from https://github.com/stubbornella/csslint // Depends on csslint.js from https://github.com/stubbornella/csslint
// declare global: CSSLint // declare global: CSSLint
(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) {
"use strict";
CodeMirror.registerHelper("lint", "css", function(text) { CodeMirror.registerHelper("lint", "css", function(text) {
var found = []; var found = [];
if (!window.CSSLint) return found;
var results = CSSLint.verify(text), messages = results.messages, message = null; var results = CSSLint.verify(text), messages = results.messages, message = null;
for ( var i = 0; i < messages.length; i++) { for ( var i = 0; i < messages.length; i++) {
message = messages[i]; message = messages[i];
@@ -17,3 +31,5 @@ CodeMirror.registerHelper("lint", "css", function(text) {
} }
return found; return found;
}); });
});

View File

@@ -0,0 +1,46 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Depends on htmlhint.js from http://htmlhint.com/js/htmlhint.js
// declare global: HTMLHint
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("htmlhint"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "htmlhint"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var defaultRules = {
"tagname-lowercase": true,
"attr-lowercase": true,
"attr-value-double-quotes": true,
"doctype-first": false,
"tag-pair": true,
"spec-char-escape": true,
"id-unique": true,
"src-not-empty": true,
"attr-no-duplication": true
};
CodeMirror.registerHelper("lint", "html", function(text, options) {
var found = [];
if (!window.HTMLHint) return found;
var messages = HTMLHint.verify(text, options && options.rules || defaultRules);
for (var i = 0; i < messages.length; i++) {
var message = messages[i];
var startLine = message.line - 1, endLine = message.line - 1, startCol = message.col - 1, endCol = message.col;
found.push({
from: CodeMirror.Pos(startLine, startCol),
to: CodeMirror.Pos(endLine, endCol),
message: message.message,
severity : message.type
});
}
return found;
});
});

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
// declare global: JSHINT // declare global: JSHINT
@@ -12,14 +22,14 @@
"Unclosed string", "Stopping, unable to continue" ]; "Unclosed string", "Stopping, unable to continue" ];
function validator(text, options) { function validator(text, options) {
JSHINT(text, options); if (!window.JSHINT) return [];
JSHINT(text, options, options.globals);
var errors = JSHINT.data().errors, result = []; var errors = JSHINT.data().errors, result = [];
if (errors) parseErrors(errors, result); if (errors) parseErrors(errors, result);
return result; return result;
} }
CodeMirror.registerHelper("lint", "javascript", validator); CodeMirror.registerHelper("lint", "javascript", validator);
CodeMirror.javascriptValidator = CodeMirror.lint.javascript; // deprecated
function cleanup(error) { function cleanup(error) {
// All problems are warnings by default // All problems are warnings by default
@@ -123,4 +133,4 @@
} }
} }
} }
})(); });

View File

@@ -1,7 +1,20 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Depends on jsonlint.js from https://github.com/zaach/jsonlint // Depends on jsonlint.js from https://github.com/zaach/jsonlint
// declare global: jsonlint // declare global: jsonlint
(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) {
"use strict";
CodeMirror.registerHelper("lint", "json", function(text) { CodeMirror.registerHelper("lint", "json", function(text) {
var found = []; var found = [];
jsonlint.parseError = function(str, hash) { jsonlint.parseError = function(str, hash) {
@@ -14,4 +27,5 @@ CodeMirror.registerHelper("lint", "json", function(text) {
catch(e) {} catch(e) {}
return found; return found;
}); });
CodeMirror.jsonValidator = CodeMirror.lint.json; // deprecated
});

View File

@@ -4,10 +4,10 @@
} }
.CodeMirror-lint-tooltip { .CodeMirror-lint-tooltip {
background-color: infobackground; background-color: #ffd;
border: 1px solid black; border: 1px solid black;
border-radius: 4px 4px 4px 4px; border-radius: 4px 4px 4px 4px;
color: infotext; color: black;
font-family: monospace; font-family: monospace;
font-size: 10pt; font-size: 10pt;
overflow: hidden; overflow: hidden;

View File

@@ -1,7 +1,16 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
var GUTTER_ID = "CodeMirror-lint-markers"; var GUTTER_ID = "CodeMirror-lint-markers";
var SEVERITIES = /^(?:error|warning)$/;
function showTooltip(e, content) { function showTooltip(e, content) {
var tt = document.createElement("div"); var tt = document.createElement("div");
@@ -37,6 +46,7 @@
} }
var poll = setInterval(function() { var poll = setInterval(function() {
if (tooltip) for (var n = node;; n = n.parentNode) { if (tooltip) for (var n = node;; n = n.parentNode) {
if (n && n.nodeType == 11) n = n.host;
if (n == document.body) return; if (n == document.body) return;
if (!n) { hide(); break; } if (!n) { hide(); break; }
} }
@@ -51,13 +61,12 @@
this.timeout = null; this.timeout = null;
this.hasGutter = hasGutter; this.hasGutter = hasGutter;
this.onMouseOver = function(e) { onMouseOver(cm, e); }; this.onMouseOver = function(e) { onMouseOver(cm, e); };
this.waitingFor = 0
} }
function parseOptions(cm, options) { function parseOptions(_cm, options) {
if (options instanceof Function) return {getAnnotations: options}; if (options instanceof Function) return {getAnnotations: options};
if (!options || options === true) options = {}; if (!options || options === true) options = {};
if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint");
if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
return options; return options;
} }
@@ -100,19 +109,44 @@
function annotationTooltip(ann) { function annotationTooltip(ann) {
var severity = ann.severity; var severity = ann.severity;
if (!SEVERITIES.test(severity)) severity = "error"; if (!severity) severity = "error";
var tip = document.createElement("div"); var tip = document.createElement("div");
tip.className = "CodeMirror-lint-message-" + severity; tip.className = "CodeMirror-lint-message-" + severity;
tip.appendChild(document.createTextNode(ann.message)); tip.appendChild(document.createTextNode(ann.message));
return tip; return tip;
} }
function lintAsync(cm, getAnnotations, passOptions) {
var state = cm.state.lint
var id = ++state.waitingFor
function abort() {
id = -1
cm.off("change", abort)
}
cm.on("change", abort)
getAnnotations(cm.getValue(), function(annotations, arg2) {
cm.off("change", abort)
if (state.waitingFor != id) return
if (arg2 && annotations instanceof CodeMirror) annotations = arg2
updateLinting(cm, annotations)
}, passOptions, cm);
}
function startLinting(cm) { function startLinting(cm) {
var state = cm.state.lint, options = state.options; var state = cm.state.lint, options = state.options;
if (options.async) var passOptions = options.options || options; // Support deprecated passing of `options` property in options
options.getAnnotations(cm, updateLinting, options); var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
else if (!getAnnotations) return;
updateLinting(cm, options.getAnnotations(cm.getValue(), options.options)); if (options.async || getAnnotations.async) {
lintAsync(cm, getAnnotations, passOptions)
} else {
var annotations = getAnnotations(cm.getValue(), passOptions, cm);
if (!annotations) return;
if (annotations.then) annotations.then(function(issues) {
updateLinting(cm, issues);
});
else updateLinting(cm, annotations);
}
} }
function updateLinting(cm, annotationsNotSorted) { function updateLinting(cm, annotationsNotSorted) {
@@ -131,7 +165,7 @@
for (var i = 0; i < anns.length; ++i) { for (var i = 0; i < anns.length; ++i) {
var ann = anns[i]; var ann = anns[i];
var severity = ann.severity; var severity = ann.severity;
if (!SEVERITIES.test(severity)) severity = "error"; if (!severity) severity = "error";
maxSeverity = getMaxSeverity(maxSeverity, severity); maxSeverity = getMaxSeverity(maxSeverity, severity);
if (options.formatAnnotation) ann = options.formatAnnotation(ann); if (options.formatAnnotation) ann = options.formatAnnotation(ann);
@@ -152,37 +186,42 @@
function onChange(cm) { function onChange(cm) {
var state = cm.state.lint; var state = cm.state.lint;
if (!state) return;
clearTimeout(state.timeout); clearTimeout(state.timeout);
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500); state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
} }
function popupSpanTooltip(ann, e) { function popupTooltips(annotations, e) {
var target = e.target || e.srcElement; var target = e.target || e.srcElement;
showTooltipFor(e, annotationTooltip(ann), target); var tooltip = document.createDocumentFragment();
for (var i = 0; i < annotations.length; i++) {
var ann = annotations[i];
tooltip.appendChild(annotationTooltip(ann));
}
showTooltipFor(e, tooltip, target);
} }
// When the mouseover fires, the cursor might not actually be over
// the character itself yet. These pairs of x,y offsets are used to
// probe a few nearby points when no suitable marked range is found.
var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0];
function onMouseOver(cm, e) { function onMouseOver(cm, e) {
if (!/\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return; var target = e.target || e.srcElement;
for (var i = 0; i < nearby.length; i += 2) { if (!/\bCodeMirror-lint-mark-/.test(target.className)) return;
var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i], var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2;
top: e.clientY + nearby[i + 1]})); var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client"));
for (var j = 0; j < spans.length; ++j) {
var span = spans[j], ann = span.__annotation; var annotations = [];
if (ann) return popupSpanTooltip(ann, e); for (var i = 0; i < spans.length; ++i) {
} var ann = spans[i].__annotation;
if (ann) annotations.push(ann);
} }
if (annotations.length) popupTooltips(annotations, e);
} }
function optionHandler(cm, val, old) { CodeMirror.defineOption("lint", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) { if (old && old != CodeMirror.Init) {
clearMarks(cm); clearMarks(cm);
cm.off("change", onChange); if (cm.state.lint.options.lintOnChange !== false)
cm.off("change", onChange);
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver); CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
clearTimeout(cm.state.lint.timeout);
delete cm.state.lint; delete cm.state.lint;
} }
@@ -190,14 +229,16 @@
var gutters = cm.getOption("gutters"), hasLintGutter = false; var gutters = cm.getOption("gutters"), hasLintGutter = false;
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true; for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter); var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
cm.on("change", onChange); if (state.options.lintOnChange !== false)
if (state.options.tooltips != false) cm.on("change", onChange);
if (state.options.tooltips != false && state.options.tooltips != "gutter")
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver); CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
startLinting(cm); startLinting(cm);
} }
} });
CodeMirror.defineOption("lintWith", false, optionHandler); // deprecated CodeMirror.defineExtension("performLint", function() {
CodeMirror.defineOption("lint", false, optionHandler); // deprecated if (this.state.lint) startLinting(this);
})(); });
});

View File

@@ -0,0 +1,35 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
// Depends on js-yaml.js from https://github.com/nodeca/js-yaml
// declare global: jsyaml
CodeMirror.registerHelper("lint", "yaml", function(text) {
var found = [];
try { jsyaml.load(text); }
catch(e) {
var loc = e.mark,
// js-yaml YAMLException doesn't always provide an accurate lineno
// e.g., when there are multiple yaml docs
// ---
// ---
// foo:bar
from = loc ? CodeMirror.Pos(loc.line, loc.column) : CodeMirror.Pos(0, 0),
to = from;
found.push({ from: from, to: to, message: e.message });
}
return found;
});
});

View File

@@ -1,50 +0,0 @@
// From https://code.google.com/p/google-diff-match-patch/ , licensed under the Apache License 2.0
(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}
diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,
b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a};
diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,
d):this.diff_bisect_(a,b,d)};
diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=d=b=0,f="",g="";b<a.length;){switch(a[b][0]){case 1:e++;g+=a[b][1];break;case -1:d++;f+=a[b][1];break;case 0:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=d.length}d=e=0;g=f=""}b++}a.pop();return a};
diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++)j[k]=-1,i[k]=-1;j[g+1]=0;i[g+1]=0;for(var k=d-e,q=0!=k%2,r=0,t=0,p=0,w=0,v=0;v<f&&!((new Date).getTime()>c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]<j[l+1]?j[l+1]:j[l-1]+1;for(var s=m-n;m<d&&s<e&&a.charAt(m)==b.charAt(s);)m++,s++;j[l]=m;if(m>d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l<h&&-1!=i[l])){var u=d-i[l];if(m>=
u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]<i[l+1]?i[l+1]:i[l-1]+1;for(m=u-n;u<d&&m<e&&a.charAt(d-u-1)==b.charAt(e-m-1);)u++,m++;i[l]=u;if(u>d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l<h&&-1!=j[l])&&(m=j[l],s=g+m-l,u=d-u,m>=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]};
diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};
diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf("\n",c);-1==f&&(f=a.length-1);var r=a.substring(c,f+1),c=f+1;(e.hasOwnProperty?e.hasOwnProperty(r):void 0!==e[r])?b+=String.fromCharCode(e[r]):(b+=String.fromCharCode(g),e[r]=g,d[g++]=r)}return b}var d=[],e={};d[0]="";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};
diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;for(var d=0,e=1;;){var f=a.substring(c-e),f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};
diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g="",h,j,n,l;-1!=(e=b.indexOf(d,e+1));){var m=f.diff_commonPrefix(a.substring(c),b.substring(e)),s=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<s+m&&(g=b.substring(e-s,e)+b.substring(e,e+m),h=a.substring(0,c-s),j=a.substring(c+m),n=b.substring(0,e-s),l=b.substring(e+m))}return 2*g.length>=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null;
var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4)),d=c(d,e,Math.ceil(d.length/2)),h;if(!g&&!d)return null;h=d?g?g[4].length>d[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]};
diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;)0==a[f][0]?(c[d++]=f,g=j,h=i,i=j=0,e=a[f][1]):(1==a[f][0]?j+=a[f][1].length:i+=a[f][1].length,e&&(e.length<=Math.max(g,h)&&e.length<=Math.max(j,i))&&(a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,d--,f=0<d?c[d-1]:-1,i=j=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(-1==a[f-1][0]&&1==a[f][0]){b=a[f-1][1];c=a[f][1];
d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}};
diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_);
return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(0==a[c-1][0]&&0==a[c+1][0]){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g)var h=e.substring(e.length-g),d=d.substring(0,d.length-g),e=h+e.substring(0,e.length-g),f=h+f;for(var g=d,h=e,j=f,i=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){var d=d+e.charAt(0),e=e.substring(1)+f.charAt(0),f=f.substring(1),k=b(d,e)+b(e,f);k>=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]=
h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;
diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;f<a.length;){if(0==a[f][0])a[f][1].length<this.Diff_EditCost&&(j||i)?(c[d++]=f,g=j,h=i,e=a[f][1]):(d=0,e=null),j=i=!1;else if(-1==a[f][0]?i=!0:j=!0,e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&3==g+h+j+i))a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,e=null,g&&h?(j=i=!0,d=0):(d--,f=0<d?c[d-1]:-1,j=i=!1),b=!0;f++}b&&this.diff_cleanupMerge(a)};
diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case -1:c++;e+=a[b][1];b++;break;case 0:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&0==a[b-c-d-1][0]?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[0,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-g)+a[b][1],f=f.substring(0,f.length-
g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[1,f]):0===d?a.splice(b-c,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&0==a[b-1][0]?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=""}""===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)0==a[b-1][0]&&0==a[b+1][0]&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,
a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){1!==a[g][0]&&(c+=a[g][1].length);-1!==a[g][0]&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)};
diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\n/g,g=0;g<a.length;g++){var h=a[g][0],j=a[g][1],j=j.replace(c,"&amp;").replace(d,"&lt;").replace(e,"&gt;").replace(f,"&para;<br>");switch(h){case 1:b[g]='<ins style="background:#e6ffe6;">'+j+"</ins>";break;case -1:b[g]='<del style="background:#ffe6e6;">'+j+"</del>";break;case 0:b[g]="<span>"+j+"</span>"}}return b.join("")};
diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)-1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case -1:d+=g.length;break;case 0:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};
diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case -1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")};
diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case "+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case "-":case "=":var i=parseInt(h,10);if(isNaN(i)||0>i)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);"="==f[g].charAt(0)?c[d++]=[0,h]:c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+
f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};
diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return!f.Match_Distance?g?1:e:e+g/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<<b.length-1,h=-1,i,k,q=b.length+a.length,r,t=0;t<b.length;t++){i=0;for(k=q;i<k;)d(t,c+
k)<=g?i=k:q=k,k=Math.floor((q-i)/2+i);q=k;i=Math.max(1,c-k+1);var p=Math.min(c+k,a.length)+b.length;k=Array(p+2);for(k[p+1]=(1<<t)-1;p>=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h};
diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};
diff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+=
c.length+d.length;a.length2+=c.length+d.length}};
diff_match_patch.prototype.patch_make=function(a,b,c){var d;if("string"==typeof a&&"string"==typeof b&&"undefined"==typeof c)d=a,b=this.diff_main(d,b,!0),2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b));else if(a&&"object"==typeof a&&"undefined"==typeof b&&"undefined"==typeof c)b=a,d=this.diff_text1(b);else if("string"==typeof a&&b&&"object"==typeof b&&"undefined"==typeof c)d=a;else if("string"==typeof a&&"string"==typeof b&&c&&"object"==typeof c)d=a,b=c;else throw Error("Unknown call format to patch_make.");
if(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];!e&&0!==i&&(a.start1=f,a.start2=g);switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case -1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:k.length<=2*this.Patch_Margin&&e&&b.length!=j+1?(a.diffs[e++]=b[j],a.length1+=k.length,a.length2+=k.length):k.length>=2*this.Patch_Margin&&
e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};
diff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g);
if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;i<a[f].diffs.length;i++){var q=a[f].diffs[i];0!==q[0]&&(k=this.diff_xIndex(g,h));1===q[0]?b=b.substring(0,
j+k)+q[1]+b.substring(j+k):-1===q[0]&&(b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+q[1].length)));-1!==q[0]&&(h+=q[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};
diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;var d=a[0],e=d.diffs;if(0==e.length||0!=e[0][0])e.unshift([0,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0,
c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};
diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,j=!0;h.start1=e-g.length;h.start2=f-g.length;""!==g&&(h.length1=h.length2=g.length,h.diffs.push([0,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){var g=d.diffs[0][0],i=d.diffs[0][1];1===g?(h.length2+=i.length,f+=i.length,h.diffs.push(d.diffs.shift()),
j=!1):-1===g&&1==h.diffs.length&&0==h.diffs[0][0]&&i.length>2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&&
(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")};
diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);""===e[2]?(f.start1--,f.length1=1):"0"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);""===e[4]?(f.start2--,f.length2=1):"0"==e[4]?f.length2=0:(f.start2--,f.length2=
parseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if("-"==e)f.diffs.push([-1,g]);else if("+"==e)f.diffs.push([1,g]);else if(" "==e)f.diffs.push([0,g]);else if("@"==e)break;else if(""!==e)throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};
diff_match_patch.patch_obj.prototype.toString=function(){var a,b;a=0===this.length1?this.start1+",0":1==this.length1?this.start1+1:this.start1+1+","+this.length1;b=0===this.length2?this.start2+",0":1==this.length2?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case -1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")};
this.diff_match_patch=diff_match_patch;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})()

View File

@@ -60,6 +60,13 @@
position: absolute; position: absolute;
cursor: pointer; cursor: pointer;
color: #44c; color: #44c;
z-index: 3;
}
.CodeMirror-merge-copy-reverse {
position: absolute;
cursor: pointer;
color: #44c;
} }
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; } .CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
@@ -90,3 +97,17 @@
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; } .CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; } .CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; } .CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
.CodeMirror-merge-collapsed-widget:before {
content: "(...)";
}
.CodeMirror-merge-collapsed-widget {
cursor: pointer;
color: #88b;
background: #eef;
border: 1px solid #ddf;
font-size: 90%;
padding: 0 3px;
border-radius: 4px;
}
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), "cjs");
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], function(CM) { mod(CM, "amd"); });
else // Plain browser env
mod(CodeMirror, "plain");
})(function(CodeMirror, env) {
if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js"; if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js";
var loading = {}; var loading = {};
@@ -25,21 +35,24 @@
if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont);
if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
var script = document.createElement("script"); var file = CodeMirror.modeURL.replace(/%N/g, mode);
script.src = CodeMirror.modeURL.replace(/%N/g, mode); if (env == "plain") {
var others = document.getElementsByTagName("script")[0]; var script = document.createElement("script");
others.parentNode.insertBefore(script, others); script.src = file;
var list = loading[mode] = [cont]; var others = document.getElementsByTagName("script")[0];
var count = 0, poll = setInterval(function() { var list = loading[mode] = [cont];
if (++count > 100) return clearInterval(poll); CodeMirror.on(script, "load", function() {
if (CodeMirror.modes.hasOwnProperty(mode)) {
clearInterval(poll);
loading[mode] = null;
ensureDeps(mode, function() { ensureDeps(mode, function() {
for (var i = 0; i < list.length; ++i) list[i](); for (var i = 0; i < list.length; ++i) list[i]();
}); });
} });
}, 200); others.parentNode.insertBefore(script, others);
} else if (env == "cjs") {
require(file);
cont();
} else if (env == "amd") {
requirejs([file], cont);
}
}; };
CodeMirror.autoLoadMode = function(instance, mode) { CodeMirror.autoLoadMode = function(instance, mode) {
@@ -48,4 +61,4 @@
instance.setOption("mode", instance.getOption("mode")); instance.setOption("mode", instance.getOption("mode"));
}); });
}; };
}()); });

View File

@@ -1,12 +1,27 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.multiplexingMode = function(outer /*, others */) { CodeMirror.multiplexingMode = function(outer /*, others */) {
// Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
var others = Array.prototype.slice.call(arguments, 1); var others = Array.prototype.slice.call(arguments, 1);
var n_others = others.length;
function indexOf(string, pattern, from) { function indexOf(string, pattern, from, returnEnd) {
if (typeof pattern == "string") return string.indexOf(pattern, from); if (typeof pattern == "string") {
var found = string.indexOf(pattern, from);
return returnEnd && found > -1 ? found + pattern.length : found;
}
var m = pattern.exec(from ? string.slice(from) : string); var m = pattern.exec(from ? string.slice(from) : string);
return m ? m.index + from : -1; return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1;
} }
return { return {
@@ -29,14 +44,14 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
token: function(stream, state) { token: function(stream, state) {
if (!state.innerActive) { if (!state.innerActive) {
var cutOff = Infinity, oldContent = stream.string; var cutOff = Infinity, oldContent = stream.string;
for (var i = 0; i < n_others; ++i) { for (var i = 0; i < others.length; ++i) {
var other = others[i]; var other = others[i];
var found = indexOf(oldContent, other.open, stream.pos); var found = indexOf(oldContent, other.open, stream.pos);
if (found == stream.pos) { if (found == stream.pos) {
stream.match(other.open); if (!other.parseDelimiters) stream.match(other.open);
state.innerActive = other; state.innerActive = other;
state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
return other.delimStyle; return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
} else if (found != -1 && found < cutOff) { } else if (found != -1 && found < cutOff) {
cutOff = found; cutOff = found;
} }
@@ -51,18 +66,21 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
state.innerActive = state.inner = null; state.innerActive = state.inner = null;
return this.token(stream, state); return this.token(stream, state);
} }
var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos) : -1; var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1;
if (found == stream.pos) { if (found == stream.pos && !curInner.parseDelimiters) {
stream.match(curInner.close); stream.match(curInner.close);
state.innerActive = state.inner = null; state.innerActive = state.inner = null;
return curInner.delimStyle; return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close");
} }
if (found > -1) stream.string = oldContent.slice(0, found); if (found > -1) stream.string = oldContent.slice(0, found);
var innerToken = curInner.mode.token(stream, state.inner); var innerToken = curInner.mode.token(stream, state.inner);
if (found > -1) stream.string = oldContent; if (found > -1) stream.string = oldContent;
if (found == stream.pos && curInner.parseDelimiters)
state.innerActive = state.inner = null;
if (curInner.innerStyle) { if (curInner.innerStyle) {
if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle; if (innerToken) innerToken = innerToken + " " + curInner.innerStyle;
else innerToken = curInner.innerStyle; else innerToken = curInner.innerStyle;
} }
@@ -82,7 +100,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
mode.blankLine(state.innerActive ? state.inner : state.outer); mode.blankLine(state.innerActive ? state.inner : state.outer);
} }
if (!state.innerActive) { if (!state.innerActive) {
for (var i = 0; i < n_others; ++i) { for (var i = 0; i < others.length; ++i) {
var other = others[i]; var other = others[i];
if (other.open === "\n") { if (other.open === "\n") {
state.innerActive = other; state.innerActive = other;
@@ -101,3 +119,5 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
} }
}; };
}; };
});

View File

@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() { (function() {
CodeMirror.defineMode("markdown_with_stex", function(){ CodeMirror.defineMode("markdown_with_stex", function(){
var inner = CodeMirror.getMode({}, "stex"); var inner = CodeMirror.getMode({}, "stex");
@@ -26,5 +29,5 @@
MT( MT(
"stexInsideMarkdown", "stexInsideMarkdown",
"[strong **Equation:**] [delim $][inner&tag \\pi][delim $]"); "[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]");
})(); })();

View File

@@ -1,20 +1,34 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Utility function that allows modes to be combined. The mode given // Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode // as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which // functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the // can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the // text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true, in which case // overlay wins, unless the combine argument was true and not overridden,
// the styles are combined. // or state.overlay.combineTokens was true, in which case the styles are
// combined.
// overlayParser is the old, deprecated name (function(mod) {
CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, combine) { 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) {
"use strict";
CodeMirror.overlayMode = function(base, overlay, combine) {
return { return {
startState: function() { startState: function() {
return { return {
base: CodeMirror.startState(base), base: CodeMirror.startState(base),
overlay: CodeMirror.startState(overlay), overlay: CodeMirror.startState(overlay),
basePos: 0, baseCur: null, basePos: 0, baseCur: null,
overlayPos: 0, overlayCur: null overlayPos: 0, overlayCur: null,
streamSeen: null
}; };
}, },
copyState: function(state) { copyState: function(state) {
@@ -27,6 +41,12 @@ CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, comb
}, },
token: function(stream, state) { token: function(stream, state) {
if (stream != state.streamSeen ||
Math.min(state.basePos, state.overlayPos) < stream.start) {
state.streamSeen = stream;
state.basePos = state.overlayPos = stream.start;
}
if (stream.start == state.basePos) { if (stream.start == state.basePos) {
state.baseCur = base.token(stream, state.base); state.baseCur = base.token(stream, state.base);
state.basePos = stream.pos; state.basePos = stream.pos;
@@ -37,10 +57,14 @@ CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, comb
state.overlayPos = stream.pos; state.overlayPos = stream.pos;
} }
stream.pos = Math.min(state.basePos, state.overlayPos); stream.pos = Math.min(state.basePos, state.overlayPos);
if (stream.eol()) state.basePos = state.overlayPos = 0;
// state.overlay.combineTokens always takes precedence over combine,
// unless set to null
if (state.overlayCur == null) return state.baseCur; if (state.overlayCur == null) return state.baseCur;
if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur; else if (state.baseCur != null &&
state.overlay.combineTokens ||
combine && state.overlay.combineTokens == null)
return state.baseCur + " " + state.overlayCur;
else return state.overlayCur; else return state.overlayCur;
}, },
@@ -52,8 +76,15 @@ CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, comb
innerMode: function(state) { return {state: state.base, mode: base}; }, innerMode: function(state) { return {state: state.base, mode: base}; },
blankLine: function(state) { blankLine: function(state) {
if (base.blankLine) base.blankLine(state.base); var baseToken, overlayToken;
if (overlay.blankLine) overlay.blankLine(state.overlay); if (base.blankLine) baseToken = base.blankLine(state.base);
if (overlay.blankLine) overlayToken = overlay.blankLine(state.overlay);
return overlayToken == null ?
baseToken :
(combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken);
} }
}; };
}; };
});

View File

@@ -0,0 +1,213 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.defineSimpleMode = function(name, states) {
CodeMirror.defineMode(name, function(config) {
return CodeMirror.simpleMode(config, states);
});
};
CodeMirror.simpleMode = function(config, states) {
ensureState(states, "start");
var states_ = {}, meta = states.meta || {}, hasIndentation = false;
for (var state in states) if (state != meta && states.hasOwnProperty(state)) {
var list = states_[state] = [], orig = states[state];
for (var i = 0; i < orig.length; i++) {
var data = orig[i];
list.push(new Rule(data, states));
if (data.indent || data.dedent) hasIndentation = true;
}
}
var mode = {
startState: function() {
return {state: "start", pending: null,
local: null, localState: null,
indent: hasIndentation ? [] : null};
},
copyState: function(state) {
var s = {state: state.state, pending: state.pending,
local: state.local, localState: null,
indent: state.indent && state.indent.slice(0)};
if (state.localState)
s.localState = CodeMirror.copyState(state.local.mode, state.localState);
if (state.stack)
s.stack = state.stack.slice(0);
for (var pers = state.persistentStates; pers; pers = pers.next)
s.persistentStates = {mode: pers.mode,
spec: pers.spec,
state: pers.state == state.localState ? s.localState : CodeMirror.copyState(pers.mode, pers.state),
next: s.persistentStates};
return s;
},
token: tokenFunction(states_, config),
innerMode: function(state) { return state.local && {mode: state.local.mode, state: state.localState}; },
indent: indentFunction(states_, meta)
};
if (meta) for (var prop in meta) if (meta.hasOwnProperty(prop))
mode[prop] = meta[prop];
return mode;
};
function ensureState(states, name) {
if (!states.hasOwnProperty(name))
throw new Error("Undefined state " + name + " in simple mode");
}
function toRegex(val, caret) {
if (!val) return /(?:)/;
var flags = "";
if (val instanceof RegExp) {
if (val.ignoreCase) flags = "i";
val = val.source;
} else {
val = String(val);
}
return new RegExp((caret === false ? "" : "^") + "(?:" + val + ")", flags);
}
function asToken(val) {
if (!val) return null;
if (typeof val == "string") return val.replace(/\./g, " ");
var result = [];
for (var i = 0; i < val.length; i++)
result.push(val[i] && val[i].replace(/\./g, " "));
return result;
}
function Rule(data, states) {
if (data.next || data.push) ensureState(states, data.next || data.push);
this.regex = toRegex(data.regex);
this.token = asToken(data.token);
this.data = data;
}
function tokenFunction(states, config) {
return function(stream, state) {
if (state.pending) {
var pend = state.pending.shift();
if (state.pending.length == 0) state.pending = null;
stream.pos += pend.text.length;
return pend.token;
}
if (state.local) {
if (state.local.end && stream.match(state.local.end)) {
var tok = state.local.endToken || null;
state.local = state.localState = null;
return tok;
} else {
var tok = state.local.mode.token(stream, state.localState), m;
if (state.local.endScan && (m = state.local.endScan.exec(stream.current())))
stream.pos = stream.start + m.index;
return tok;
}
}
var curState = states[state.state];
for (var i = 0; i < curState.length; i++) {
var rule = curState[i];
var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex);
if (matches) {
if (rule.data.next) {
state.state = rule.data.next;
} else if (rule.data.push) {
(state.stack || (state.stack = [])).push(state.state);
state.state = rule.data.push;
} else if (rule.data.pop && state.stack && state.stack.length) {
state.state = state.stack.pop();
}
if (rule.data.mode)
enterLocalMode(config, state, rule.data.mode, rule.token);
if (rule.data.indent)
state.indent.push(stream.indentation() + config.indentUnit);
if (rule.data.dedent)
state.indent.pop();
if (matches.length > 2) {
state.pending = [];
for (var j = 2; j < matches.length; j++)
if (matches[j])
state.pending.push({text: matches[j], token: rule.token[j - 1]});
stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0));
return rule.token[0];
} else if (rule.token && rule.token.join) {
return rule.token[0];
} else {
return rule.token;
}
}
}
stream.next();
return null;
};
}
function cmp(a, b) {
if (a === b) return true;
if (!a || typeof a != "object" || !b || typeof b != "object") return false;
var props = 0;
for (var prop in a) if (a.hasOwnProperty(prop)) {
if (!b.hasOwnProperty(prop) || !cmp(a[prop], b[prop])) return false;
props++;
}
for (var prop in b) if (b.hasOwnProperty(prop)) props--;
return props == 0;
}
function enterLocalMode(config, state, spec, token) {
var pers;
if (spec.persistent) for (var p = state.persistentStates; p && !pers; p = p.next)
if (spec.spec ? cmp(spec.spec, p.spec) : spec.mode == p.mode) pers = p;
var mode = pers ? pers.mode : spec.mode || CodeMirror.getMode(config, spec.spec);
var lState = pers ? pers.state : CodeMirror.startState(mode);
if (spec.persistent && !pers)
state.persistentStates = {mode: mode, spec: spec.spec, state: lState, next: state.persistentStates};
state.localState = lState;
state.local = {mode: mode,
end: spec.end && toRegex(spec.end),
endScan: spec.end && spec.forceEnd !== false && toRegex(spec.end, false),
endToken: token && token.join ? token[token.length - 1] : token};
}
function indexOf(val, arr) {
for (var i = 0; i < arr.length; i++) if (arr[i] === val) return true;
}
function indentFunction(states, meta) {
return function(state, textAfter, line) {
if (state.local && state.local.mode.indent)
return state.local.mode.indent(state.localState, textAfter, line);
if (state.indent == null || state.local || meta.dontIndentStates && indexOf(state.state, meta.dontIndentStates) > -1)
return CodeMirror.Pass;
var pos = state.indent.length - 1, rules = states[state.state];
scan: for (;;) {
for (var i = 0; i < rules.length; i++) {
var rule = rules[i];
if (rule.data.dedent && rule.data.dedentIfLineStart !== false) {
var m = rule.regex.exec(textAfter);
if (m && m[0]) {
pos--;
if (rule.next || rule.push) rules = states[rule.next || rule.push];
textAfter = textAfter.slice(m[0].length);
continue scan;
}
}
}
break;
}
return pos < 0 ? 0 : state.indent[pos];
};
}
});

View File

@@ -1,4 +1,15 @@
CodeMirror.colorize = (function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./runmode"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./runmode"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/; var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/;
@@ -10,7 +21,7 @@ CodeMirror.colorize = (function() {
} }
} }
return function(collection, defaultMode) { CodeMirror.colorize = function(collection, defaultMode) {
if (!collection) collection = document.body.getElementsByTagName("pre"); if (!collection) collection = document.body.getElementsByTagName("pre");
for (var i = 0; i < collection.length; ++i) { for (var i = 0; i < collection.length; ++i) {
@@ -26,4 +37,4 @@ CodeMirror.colorize = (function() {
node.className += " cm-s-default"; node.className += " cm-s-default";
} }
}; };
})(); });

View File

@@ -1,4 +1,5 @@
/* Just enough of CodeMirror to run runMode under node.js */ // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
window.CodeMirror = {}; window.CodeMirror = {};
@@ -73,7 +74,11 @@ CodeMirror.startState = function (mode, a1, a2) {
}; };
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
CodeMirror.defineMode = function (name, mode) { modes[name] = mode; }; CodeMirror.defineMode = function (name, mode) {
if (arguments.length > 2)
mode.dependencies = Array.prototype.slice.call(arguments, 2);
modes[name] = mode;
};
CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; }; CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
CodeMirror.resolveMode = function(spec) { CodeMirror.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
@@ -141,6 +146,7 @@ CodeMirror.runMode = function (string, modespec, callback, options) {
for (var i = 0, e = lines.length; i < e; ++i) { for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n"); 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()) { while (!stream.eol()) {
var style = mode.token(stream, state); var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state); callback(stream.current(), style, i, stream.start, state);

View File

@@ -1,9 +1,22 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.runMode = function(string, modespec, callback, options) { CodeMirror.runMode = function(string, modespec, callback, options) {
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
var ie = /MSIE \d/.test(navigator.userAgent); var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
if (callback.nodeType == 1) { if (callback.appendChild) {
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
var node = callback, col = 0; var node = callback, col = 0;
node.innerHTML = ""; node.innerHTML = "";
@@ -47,6 +60,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
for (var i = 0, e = lines.length; i < e; ++i) { for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n"); 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()) { while (!stream.eol()) {
var style = mode.token(stream, state); var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state); callback(stream.current(), style, i, stream.start, state);
@@ -54,3 +68,5 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
} }
} }
}; };
});

View File

@@ -1,16 +1,39 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
/* Just enough of CodeMirror to run runMode under node.js */ /* Just enough of CodeMirror to run runMode under node.js */
function splitLines(string){ return string.split(/\r?\n|\r/); }; function splitLines(string){return string.split(/\r\n?|\n/);};
function StringStream(string) { // Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
var countColumn = function(string, end, tabSize, startIndex, startValue) {
if (end == null) {
end = string.search(/[^\s\u00a0]/);
if (end == -1) end = string.length;
}
for (var i = startIndex || 0, n = startValue || 0;;) {
var nextTab = string.indexOf("\t", i);
if (nextTab < 0 || nextTab >= end)
return n + (end - i);
n += nextTab - i;
n += tabSize - (n % tabSize);
i = nextTab + 1;
}
};
function StringStream(string, tabSize) {
this.pos = this.start = 0; this.pos = this.start = 0;
this.string = string; this.string = string;
this.tabSize = tabSize || 8;
this.lastColumnPos = this.lastColumnValue = 0;
this.lineStart = 0; this.lineStart = 0;
} };
StringStream.prototype = { StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;}, eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == 0;}, sol: function() {return this.pos == this.lineStart;},
peek: function() {return this.string.charAt(this.pos) || null;}, peek: function() {return this.string.charAt(this.pos) || undefined;},
next: function() { next: function() {
if (this.pos < this.string.length) if (this.pos < this.string.length)
return this.string.charAt(this.pos++); return this.string.charAt(this.pos++);
@@ -37,8 +60,17 @@ StringStream.prototype = {
if (found > -1) {this.pos = found; return true;} if (found > -1) {this.pos = found; return true;}
}, },
backUp: function(n) {this.pos -= n;}, backUp: function(n) {this.pos -= n;},
column: function() {return this.start - this.lineStart;}, column: function() {
indentation: function() {return 0;}, if (this.lastColumnPos < this.start) {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
}
return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
indentation: function() {
return countColumn(this.string, null, this.tabSize) -
(this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
match: function(pattern, consume, caseInsensitive) { match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") { if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
@@ -69,10 +101,8 @@ exports.startState = function(mode, a1, a2) {
var modes = exports.modes = {}, mimeModes = exports.mimeModes = {}; var modes = exports.modes = {}, mimeModes = exports.mimeModes = {};
exports.defineMode = function(name, mode) { exports.defineMode = function(name, mode) {
if (arguments.length > 2) { if (arguments.length > 2)
mode.dependencies = []; mode.dependencies = Array.prototype.slice.call(arguments, 2);
for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
}
modes[name] = mode; modes[name] = mode;
}; };
exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; }; exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; };
@@ -91,20 +121,52 @@ exports.resolveMode = function(spec) {
if (typeof spec == "string") return {name: spec}; if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"}; else return spec || {name: "null"};
}; };
function copyObj(obj, target, overwrite) {
if (!target) target = {};
for (var prop in obj)
if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
target[prop] = obj[prop];
return target;
}
// This can be used to attach properties to mode objects from
// outside the actual mode definition.
var modeExtensions = exports.modeExtensions = {};
exports.extendMode = function(mode, properties) {
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
copyObj(properties, exts);
};
exports.getMode = function(options, spec) { exports.getMode = function(options, spec) {
spec = exports.resolveMode(mimeModes[spec]); var spec = exports.resolveMode(spec);
var mfactory = modes[spec.name]; var mfactory = modes[spec.name];
if (!mfactory) throw new Error("Unknown mode: " + spec); if (!mfactory) return exports.getMode(options, "text/plain");
return mfactory(options, spec); var modeObj = mfactory(options, spec);
if (modeExtensions.hasOwnProperty(spec.name)) {
var exts = modeExtensions[spec.name];
for (var prop in exts) {
if (!exts.hasOwnProperty(prop)) continue;
if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
modeObj[prop] = exts[prop];
}
}
modeObj.name = spec.name;
if (spec.helperType) modeObj.helperType = spec.helperType;
if (spec.modeProps) for (var prop in spec.modeProps)
modeObj[prop] = spec.modeProps[prop];
return modeObj;
}; };
exports.registerHelper = exports.registerGlobalHelper = Math.min; exports.registerHelper = exports.registerGlobalHelper = Math.min;
exports.runMode = function(string, modespec, callback) { exports.runMode = function(string, modespec, callback, options) {
var mode = exports.getMode({indentUnit: 2}, modespec); var mode = exports.getMode({indentUnit: 2}, modespec);
var lines = splitLines(string), state = (options && options.state) || exports.startState(mode); var lines = splitLines(string), state = (options && options.state) || exports.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) { for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n"); if (i) callback("\n");
var stream = new exports.StringStream(lines[i]); var stream = new exports.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) { while (!stream.eol()) {
var style = mode.token(stream, state); var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state); callback(stream.current(), style, i, stream.start, state);
@@ -112,3 +174,6 @@ exports.runMode = function(string, modespec, callback) {
} }
} }
}; };
require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")];
require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")];

View File

@@ -0,0 +1,122 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.defineExtension("annotateScrollbar", function(options) {
if (typeof options == "string") options = {className: options};
return new Annotation(this, options);
});
CodeMirror.defineOption("scrollButtonHeight", 0);
function Annotation(cm, options) {
this.cm = cm;
this.options = options;
this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight");
this.annotations = [];
this.doRedraw = this.doUpdate = null;
this.div = cm.getWrapperElement().appendChild(document.createElement("div"));
this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none";
this.computeScale();
function scheduleRedraw(delay) {
clearTimeout(self.doRedraw);
self.doRedraw = setTimeout(function() { self.redraw(); }, delay);
}
var self = this;
cm.on("refresh", this.resizeHandler = function() {
clearTimeout(self.doUpdate);
self.doUpdate = setTimeout(function() {
if (self.computeScale()) scheduleRedraw(20);
}, 100);
});
cm.on("markerAdded", this.resizeHandler);
cm.on("markerCleared", this.resizeHandler);
if (options.listenForChanges !== false)
cm.on("change", this.changeHandler = function() {
scheduleRedraw(250);
});
}
Annotation.prototype.computeScale = function() {
var cm = this.cm;
var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) /
cm.getScrollerElement().scrollHeight
if (hScale != this.hScale) {
this.hScale = hScale;
return true;
}
};
Annotation.prototype.update = function(annotations) {
this.annotations = annotations;
this.redraw();
};
Annotation.prototype.redraw = function(compute) {
if (compute !== false) this.computeScale();
var cm = this.cm, hScale = this.hScale;
var frag = document.createDocumentFragment(), anns = this.annotations;
var wrapping = cm.getOption("lineWrapping");
var singleLineH = wrapping && cm.defaultTextHeight() * 1.5;
var curLine = null, curLineObj = null;
function getY(pos, top) {
if (curLine != pos.line) {
curLine = pos.line;
curLineObj = cm.getLineHandle(curLine);
}
if ((curLineObj.widgets && curLineObj.widgets.length) ||
(wrapping && curLineObj.height > singleLineH))
return cm.charCoords(pos, "local")[top ? "top" : "bottom"];
var topY = cm.heightAtLine(curLineObj, "local");
return topY + (top ? 0 : curLineObj.height);
}
var lastLine = cm.lastLine()
if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
var ann = anns[i];
if (ann.to.line > lastLine) continue;
var top = nextTop || getY(ann.from, true) * hScale;
var bottom = getY(ann.to, false) * hScale;
while (i < anns.length - 1) {
if (anns[i + 1].to.line > lastLine) break;
nextTop = getY(anns[i + 1].from, true) * hScale;
if (nextTop > bottom + .9) break;
ann = anns[++i];
bottom = getY(ann.to, false) * hScale;
}
if (bottom == top) continue;
var height = Math.max(bottom - top, 3);
var elt = frag.appendChild(document.createElement("div"));
elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: "
+ (top + this.buttonHeight) + "px; height: " + height + "px";
elt.className = this.options.className;
if (ann.id) {
elt.setAttribute("annotation-id", ann.id);
}
}
this.div.textContent = "";
this.div.appendChild(frag);
};
Annotation.prototype.clear = function() {
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);
this.div.parentNode.removeChild(this.div);
};
});

View File

@@ -1,14 +1,26 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) { CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) { if (old && old != CodeMirror.Init) {
cm.off("change", onChange); cm.off("change", onChange);
cm.off("refresh", updateBottomMargin);
cm.display.lineSpace.parentNode.style.paddingBottom = ""; cm.display.lineSpace.parentNode.style.paddingBottom = "";
cm.state.scrollPastEndPadding = null; cm.state.scrollPastEndPadding = null;
} }
if (val) { if (val) {
cm.on("change", onChange); cm.on("change", onChange);
cm.on("refresh", updateBottomMargin);
updateBottomMargin(cm); updateBottomMargin(cm);
} }
}); });
@@ -28,7 +40,9 @@
if (cm.state.scrollPastEndPadding != padding) { if (cm.state.scrollPastEndPadding != padding) {
cm.state.scrollPastEndPadding = padding; cm.state.scrollPastEndPadding = padding;
cm.display.lineSpace.parentNode.style.paddingBottom = padding; cm.display.lineSpace.parentNode.style.paddingBottom = padding;
cm.off("refresh", updateBottomMargin);
cm.setSize(); cm.setSize();
cm.on("refresh", updateBottomMargin);
} }
} }
})(); });

View File

@@ -0,0 +1,66 @@
.CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div {
position: absolute;
background: #ccc;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #bbb;
border-radius: 2px;
}
.CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical {
position: absolute;
z-index: 6;
background: #eee;
}
.CodeMirror-simplescroll-horizontal {
bottom: 0; left: 0;
height: 8px;
}
.CodeMirror-simplescroll-horizontal div {
bottom: 0;
height: 100%;
}
.CodeMirror-simplescroll-vertical {
right: 0; top: 0;
width: 8px;
}
.CodeMirror-simplescroll-vertical div {
right: 0;
width: 100%;
}
.CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler {
display: none;
}
.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div {
position: absolute;
background: #bcd;
border-radius: 3px;
}
.CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical {
position: absolute;
z-index: 6;
}
.CodeMirror-overlayscroll-horizontal {
bottom: 0; left: 0;
height: 6px;
}
.CodeMirror-overlayscroll-horizontal div {
bottom: 0;
height: 100%;
}
.CodeMirror-overlayscroll-vertical {
right: 0; top: 0;
width: 6px;
}
.CodeMirror-overlayscroll-vertical div {
right: 0;
width: 100%;
}

View File

@@ -0,0 +1,152 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
function Bar(cls, orientation, scroll) {
this.orientation = orientation;
this.scroll = scroll;
this.screen = this.total = this.size = 1;
this.pos = 0;
this.node = document.createElement("div");
this.node.className = cls + "-" + orientation;
this.inner = this.node.appendChild(document.createElement("div"));
var self = this;
CodeMirror.on(this.inner, "mousedown", function(e) {
if (e.which != 1) return;
CodeMirror.e_preventDefault(e);
var axis = self.orientation == "horizontal" ? "pageX" : "pageY";
var start = e[axis], startpos = self.pos;
function done() {
CodeMirror.off(document, "mousemove", move);
CodeMirror.off(document, "mouseup", done);
}
function move(e) {
if (e.which != 1) return done();
self.moveTo(startpos + (e[axis] - start) * (self.total / self.size));
}
CodeMirror.on(document, "mousemove", move);
CodeMirror.on(document, "mouseup", done);
});
CodeMirror.on(this.node, "click", function(e) {
CodeMirror.e_preventDefault(e);
var innerBox = self.inner.getBoundingClientRect(), where;
if (self.orientation == "horizontal")
where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0;
else
where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0;
self.moveTo(self.pos + where * self.screen);
});
function onWheel(e) {
var moved = CodeMirror.wheelEventPixels(e)[self.orientation == "horizontal" ? "x" : "y"];
var oldPos = self.pos;
self.moveTo(self.pos + moved);
if (self.pos != oldPos) CodeMirror.e_preventDefault(e);
}
CodeMirror.on(this.node, "mousewheel", onWheel);
CodeMirror.on(this.node, "DOMMouseScroll", onWheel);
}
Bar.prototype.setPos = function(pos, force) {
if (pos < 0) pos = 0;
if (pos > this.total - this.screen) pos = this.total - this.screen;
if (!force && pos == this.pos) return false;
this.pos = pos;
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
(pos * (this.size / this.total)) + "px";
return true
};
Bar.prototype.moveTo = function(pos) {
if (this.setPos(pos)) this.scroll(pos, this.orientation);
}
var minButtonSize = 10;
Bar.prototype.update = function(scrollSize, clientSize, barSize) {
var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize
if (sizeChanged) {
this.screen = clientSize;
this.total = scrollSize;
this.size = barSize;
}
var buttonSize = this.screen * (this.size / this.total);
if (buttonSize < minButtonSize) {
this.size -= minButtonSize - buttonSize;
buttonSize = minButtonSize;
}
this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
buttonSize + "px";
this.setPos(this.pos, sizeChanged);
};
function SimpleScrollbars(cls, place, scroll) {
this.addClass = cls;
this.horiz = new Bar(cls, "horizontal", scroll);
place(this.horiz.node);
this.vert = new Bar(cls, "vertical", scroll);
place(this.vert.node);
this.width = null;
}
SimpleScrollbars.prototype.update = function(measure) {
if (this.width == null) {
var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle;
if (style) this.width = parseInt(style.height);
}
var width = this.width || 0;
var needsH = measure.scrollWidth > measure.clientWidth + 1;
var needsV = measure.scrollHeight > measure.clientHeight + 1;
this.vert.node.style.display = needsV ? "block" : "none";
this.horiz.node.style.display = needsH ? "block" : "none";
if (needsV) {
this.vert.update(measure.scrollHeight, measure.clientHeight,
measure.viewHeight - (needsH ? width : 0));
this.vert.node.style.bottom = needsH ? width + "px" : "0";
}
if (needsH) {
this.horiz.update(measure.scrollWidth, measure.clientWidth,
measure.viewWidth - (needsV ? width : 0) - measure.barLeft);
this.horiz.node.style.right = needsV ? width + "px" : "0";
this.horiz.node.style.left = measure.barLeft + "px";
}
return {right: needsV ? width : 0, bottom: needsH ? width : 0};
};
SimpleScrollbars.prototype.setScrollTop = function(pos) {
this.vert.setPos(pos);
};
SimpleScrollbars.prototype.setScrollLeft = function(pos) {
this.horiz.setPos(pos);
};
SimpleScrollbars.prototype.clear = function() {
var parent = this.horiz.node.parentNode;
parent.removeChild(this.horiz.node);
parent.removeChild(this.vert.node);
};
CodeMirror.scrollbarModel.simple = function(place, scroll) {
return new SimpleScrollbars("CodeMirror-simplescroll", place, scroll);
};
CodeMirror.scrollbarModel.overlay = function(place, scroll) {
return new SimpleScrollbars("CodeMirror-overlayscroll", place, scroll);
};
});

View File

@@ -0,0 +1,49 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Defines jumpToLine command. Uses dialog.js if present.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../dialog/dialog"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../dialog/dialog"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function dialog(cm, text, shortText, deflt, f) {
if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
else f(prompt(shortText, deflt));
}
var jumpDialog =
'Jump to line: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use line:column or scroll% syntax)</span>';
function interpretLine(cm, string) {
var num = Number(string)
if (/^[-+]/.test(string)) return cm.getCursor().line + num
else return num - 1
}
CodeMirror.commands.jumpToLine = function(cm) {
var cur = cm.getCursor();
dialog(cm, jumpDialog, "Jump to line:", (cur.line + 1) + ":" + cur.ch, function(posStr) {
if (!posStr) return;
var match;
if (match = /^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(posStr)) {
cm.setCursor(interpretLine(cm, match[1]), Number(match[2]))
} else if (match = /^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(posStr)) {
var line = Math.round(cm.lineCount() * Number(match[1]) / 100);
if (/^[-+]/.test(match[1])) line = cur.line + line + 1;
cm.setCursor(line - 1, cur.ch);
} else if (match = /^\s*\:?\s*([\+\-]?\d+)\s*/.exec(posStr)) {
cm.setCursor(interpretLine(cm, match[1]), cur.ch);
}
});
};
CodeMirror.keyMap["default"]["Alt-G"] = "jumpToLine";
});

View File

@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Highlighting text that matches the selection // Highlighting text that matches the selection
// //
// Defines an option highlightSelectionMatches, which, when enabled, // Defines an option highlightSelectionMatches, which, when enabled,
@@ -5,75 +8,146 @@
// document. // document.
// //
// The option can be set to true to simply enable it, or to a // The option can be set to true to simply enable it, or to a
// {minChars, style, showToken} object to explicitly configure it. // {minChars, style, wordsOnly, showToken, delay} object to explicitly
// minChars is the minimum amount of characters that should be // configure it. minChars is the minimum amount of characters that should be
// selected for the behavior to occur, and style is the token style to // selected for the behavior to occur, and style is the token style to
// apply to the matches. This will be prefixed by "cm-" to create an // apply to the matches. This will be prefixed by "cm-" to create an
// actual CSS class name. showToken, when enabled, will cause the // actual CSS class name. If wordsOnly is enabled, the matches will be
// current token to be highlighted when nothing is selected. // highlighted only if the selected text is a word. showToken, when enabled,
// will cause the current token to be highlighted when nothing is selected.
// delay is used to specify how much time to wait, in milliseconds, before
// highlighting the matches. If annotateScrollbar is enabled, the occurences
// will be highlighted on the scrollbar via the matchesonscrollbar addon.
(function() { (function(mod) {
var DEFAULT_MIN_CHARS = 2; if (typeof exports == "object" && typeof module == "object") // CommonJS
var DEFAULT_TOKEN_STYLE = "matchhighlight"; mod(require("../../lib/codemirror"), require("./matchesonscrollbar"));
var DEFAULT_DELAY = 100; else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./matchesonscrollbar"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var defaults = {
style: "matchhighlight",
minChars: 2,
delay: 100,
wordsOnly: false,
annotateScrollbar: false,
showToken: false,
trim: true
}
function State(options) { function State(options) {
if (typeof options == "object") { this.options = {}
this.minChars = options.minChars; for (var name in defaults)
this.style = options.style; this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name]
this.showToken = options.showToken;
this.delay = options.delay;
}
if (this.style == null) this.style = DEFAULT_TOKEN_STYLE;
if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS;
if (this.delay == null) this.delay = DEFAULT_DELAY;
this.overlay = this.timeout = null; this.overlay = this.timeout = null;
this.matchesonscroll = null;
this.active = false;
} }
CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) { if (old && old != CodeMirror.Init) {
var over = cm.state.matchHighlighter.overlay; removeOverlay(cm);
if (over) cm.removeOverlay(over);
clearTimeout(cm.state.matchHighlighter.timeout); clearTimeout(cm.state.matchHighlighter.timeout);
cm.state.matchHighlighter = null; cm.state.matchHighlighter = null;
cm.off("cursorActivity", cursorActivity); cm.off("cursorActivity", cursorActivity);
cm.off("focus", onFocus)
} }
if (val) { if (val) {
cm.state.matchHighlighter = new State(val); var state = cm.state.matchHighlighter = new State(val);
highlightMatches(cm); if (cm.hasFocus()) {
state.active = true
highlightMatches(cm)
} else {
cm.on("focus", onFocus)
}
cm.on("cursorActivity", cursorActivity); cm.on("cursorActivity", cursorActivity);
} }
}); });
function cursorActivity(cm) { function cursorActivity(cm) {
var state = cm.state.matchHighlighter; var state = cm.state.matchHighlighter;
if (state.active || cm.hasFocus()) scheduleHighlight(cm, state)
}
function onFocus(cm) {
var state = cm.state.matchHighlighter
if (!state.active) {
state.active = true
scheduleHighlight(cm, state)
}
}
function scheduleHighlight(cm, state) {
clearTimeout(state.timeout); clearTimeout(state.timeout);
state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay); state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay);
}
function addOverlay(cm, query, hasBoundary, style) {
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 + "\\b") : query;
state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
{className: "CodeMirror-selection-highlight-scrollbar"});
}
}
function removeOverlay(cm) {
var state = cm.state.matchHighlighter;
if (state.overlay) {
cm.removeOverlay(state.overlay);
state.overlay = null;
if (state.matchesonscroll) {
state.matchesonscroll.clear();
state.matchesonscroll = null;
}
}
} }
function highlightMatches(cm) { function highlightMatches(cm) {
cm.operation(function() { cm.operation(function() {
var state = cm.state.matchHighlighter; var state = cm.state.matchHighlighter;
if (state.overlay) { removeOverlay(cm);
cm.removeOverlay(state.overlay); if (!cm.somethingSelected() && state.options.showToken) {
state.overlay = null; var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken;
}
if (!cm.somethingSelected() && state.showToken) {
var re = state.showToken === true ? /[\w$]/ : state.showToken;
var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
while (start && re.test(line.charAt(start - 1))) --start; while (start && re.test(line.charAt(start - 1))) --start;
while (end < line.length && re.test(line.charAt(end))) ++end; while (end < line.length && re.test(line.charAt(end))) ++end;
if (start < end) if (start < end)
cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style)); addOverlay(cm, line.slice(start, end), re, state.options.style);
return; return;
} }
if (cm.getCursor("head").line != cm.getCursor("anchor").line) return; var from = cm.getCursor("from"), to = cm.getCursor("to");
var selection = cm.getSelection().replace(/^\s+|\s+$/g, ""); if (from.line != to.line) return;
if (selection.length >= state.minChars) if (state.options.wordsOnly && !isWord(cm, from, to)) return;
cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style)); var selection = cm.getRange(from, to)
if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "")
if (selection.length >= state.options.minChars)
addOverlay(cm, selection, false, state.options.style);
}); });
} }
function isWord(cm, from, to) {
var str = cm.getRange(from, to);
if (str.match(/^\w+$/) !== null) {
if (from.ch > 0) {
var pos = {line: from.line, ch: from.ch - 1};
var chr = cm.getRange(pos, from);
if (chr.match(/\W/) === null) return false;
}
if (to.ch < cm.getLine(from.line).length) {
var pos = {line: to.line, ch: to.ch + 1};
var chr = cm.getRange(to, pos);
if (chr.match(/\W/) === null) return false;
}
return true;
} else return false;
}
function boundariesAround(stream, re) { function boundariesAround(stream, re) {
return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) &&
(stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
@@ -88,4 +162,4 @@
stream.skipTo(query.charAt(0)) || stream.skipToEnd(); stream.skipTo(query.charAt(0)) || stream.skipToEnd();
}}; }};
} }
})(); });

View File

@@ -0,0 +1,8 @@
.CodeMirror-search-match {
background: gold;
border-top: 1px solid orange;
border-bottom: 1px solid orange;
-moz-box-sizing: border-box;
box-sizing: border-box;
opacity: .5;
}

View File

@@ -0,0 +1,97 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./searchcursor"), require("../scroll/annotatescrollbar"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./searchcursor", "../scroll/annotatescrollbar"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) {
if (typeof options == "string") options = {className: options};
if (!options) options = {};
return new SearchAnnotation(this, query, caseFold, options);
});
function SearchAnnotation(cm, query, caseFold, options) {
this.cm = cm;
this.options = options;
var annotateOptions = {listenForChanges: false};
for (var prop in options) annotateOptions[prop] = options[prop];
if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match";
this.annotation = cm.annotateScrollbar(annotateOptions);
this.query = query;
this.caseFold = caseFold;
this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1};
this.matches = [];
this.update = null;
this.findMatches();
this.annotation.update(this.matches);
var self = this;
cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); });
}
var MAX_MATCHES = 1000;
SearchAnnotation.prototype.findMatches = function() {
if (!this.gap) return;
for (var i = 0; i < this.matches.length; i++) {
var match = this.matches[i];
if (match.from.line >= this.gap.to) break;
if (match.to.line >= this.gap.from) this.matches.splice(i--, 1);
}
var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), this.caseFold);
var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES;
while (cursor.findNext()) {
var match = {from: cursor.from(), to: cursor.to()};
if (match.from.line >= this.gap.to) break;
this.matches.splice(i++, 0, match);
if (this.matches.length > maxMatches) break;
}
this.gap = null;
};
function offsetLine(line, changeStart, sizeChange) {
if (line <= changeStart) return line;
return Math.max(changeStart, line + sizeChange);
}
SearchAnnotation.prototype.onChange = function(change) {
var startLine = change.from.line;
var endLine = CodeMirror.changeEnd(change).line;
var sizeChange = endLine - change.to.line;
if (this.gap) {
this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line);
this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line);
} else {
this.gap = {from: change.from.line, to: endLine + 1};
}
if (sizeChange) for (var i = 0; i < this.matches.length; i++) {
var match = this.matches[i];
var newFrom = offsetLine(match.from.line, startLine, sizeChange);
if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch);
var newTo = offsetLine(match.to.line, startLine, sizeChange);
if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch);
}
clearTimeout(this.update);
var self = this;
this.update = setTimeout(function() { self.updateAfterChange(); }, 250);
};
SearchAnnotation.prototype.updateAfterChange = function() {
this.findMatches();
this.annotation.update(this.matches);
};
SearchAnnotation.prototype.clear = function() {
this.cm.off("change", this.changeHandler);
this.annotation.clear();
};
});

View File

@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Define search commands. Depends on dialog.js or another // Define search commands. Depends on dialog.js or another
// implementation of the openDialog method. // implementation of the openDialog method.
@@ -6,76 +9,162 @@
// replace by making sure the match is no longer selected when hitting // replace by making sure the match is no longer selected when hitting
// Ctrl-G. // Ctrl-G.
(function() { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function searchOverlay(query, caseInsensitive) { function searchOverlay(query, caseInsensitive) {
var startChar; if (typeof query == "string")
if (typeof query == "string") { query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
startChar = query.charAt(0); else if (!query.global)
query = new RegExp("^" + query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
caseInsensitive ? "i" : "");
} else {
query = new RegExp("^(?:" + query.source + ")", query.ignoreCase ? "i" : "");
}
if (typeof query == "string") return {token: function(stream) {
if (stream.match(query)) return "searching";
stream.next();
stream.skipTo(query.charAt(0)) || stream.skipToEnd();
}};
return {token: function(stream) { return {token: function(stream) {
if (stream.match(query)) return "searching"; query.lastIndex = stream.pos;
while (!stream.eol()) { var match = query.exec(stream.string);
stream.next(); if (match && match.index == stream.pos) {
if (startChar) stream.pos += match[0].length || 1;
stream.skipTo(startChar) || stream.skipToEnd(); return "searching";
if (stream.match(query, false)) break; } else if (match) {
stream.pos = match.index;
} else {
stream.skipToEnd();
} }
}}; }};
} }
function SearchState() { function SearchState() {
this.posFrom = this.posTo = this.query = null; this.posFrom = this.posTo = this.lastQuery = this.query = null;
this.overlay = null; this.overlay = null;
} }
function getSearchState(cm) { function getSearchState(cm) {
return cm.state.search || (cm.state.search = new SearchState()); return cm.state.search || (cm.state.search = new SearchState());
} }
function queryCaseInsensitive(query) { function queryCaseInsensitive(query) {
return typeof query == "string" && query == query.toLowerCase(); return typeof query == "string" && query == query.toLowerCase();
} }
function getSearchCursor(cm, query, pos) { function getSearchCursor(cm, query, pos) {
// Heuristic: if the query string is all lowercase, do a case insensitive search. // Heuristic: if the query string is all lowercase, do a case insensitive search.
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query)); return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
} }
function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
cm.openDialog(text, onEnter, {
value: deflt,
selectValueOnOpen: true,
closeOnEnter: false,
onClose: function() { clearSearch(cm); },
onKeyDown: onKeyDown
});
}
function dialog(cm, text, shortText, deflt, f) { function dialog(cm, text, shortText, deflt, f) {
if (cm.openDialog) cm.openDialog(text, f, {value: deflt}); if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
else f(prompt(shortText, deflt)); else f(prompt(shortText, deflt));
} }
function confirmDialog(cm, text, shortText, fs) { function confirmDialog(cm, text, shortText, fs) {
if (cm.openConfirm) cm.openConfirm(text, fs); if (cm.openConfirm) cm.openConfirm(text, fs);
else if (confirm(shortText)) fs[0](); else if (confirm(shortText)) fs[0]();
} }
function parseString(string) {
return string.replace(/\\(.)/g, function(_, ch) {
if (ch == "n") return "\n"
if (ch == "r") return "\r"
return ch
})
}
function parseQuery(query) { function parseQuery(query) {
var isRE = query.match(/^\/(.*)\/([a-z]*)$/); var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query; if (isRE) {
try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
catch(e) {} // Not a regular expression after all, do a string search
} else {
query = parseString(query)
}
if (typeof query == "string" ? query == "" : query.test(""))
query = /x^/;
return query;
} }
var queryDialog = var queryDialog =
'Search: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>'; '<span class="CodeMirror-search-label">Search:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
function doSearch(cm, rev) {
function startSearch(cm, state, query) {
state.queryText = query;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
cm.addOverlay(state.overlay);
if (cm.showMatchesOnScrollbar) {
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
}
}
function doSearch(cm, rev, persistent, immediate) {
var state = getSearchState(cm); var state = getSearchState(cm);
if (state.query) return findNext(cm, rev); if (state.query) return findNext(cm, rev);
dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) { var q = cm.getSelection() || state.lastQuery;
cm.operation(function() { if (persistent && cm.openDialog) {
if (!query || state.query) return; var hiding = null
state.query = parseQuery(query); var searchNext = function(query, event) {
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); CodeMirror.e_stop(event);
state.overlay = searchOverlay(state.query); if (!query) return;
cm.addOverlay(state.overlay); if (query != state.queryText) {
state.posFrom = state.posTo = cm.getCursor(); startSearch(cm, state, query);
findNext(cm, rev); state.posFrom = state.posTo = cm.getCursor();
}
if (hiding) hiding.style.opacity = 1
findNext(cm, event.shiftKey, function(_, to) {
var dialog
if (to.line < 3 && document.querySelector &&
(dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) &&
dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
(hiding = dialog).style.opacity = .4
})
};
persistentDialog(cm, queryDialog, q, searchNext, function(event, query) {
var keyName = CodeMirror.keyName(event)
var cmd = CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
if (!cmd) cmd = cm.getOption('extraKeys')[keyName]
if (cmd == "findNext" || cmd == "findPrev" ||
cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
CodeMirror.e_stop(event);
startSearch(cm, getSearchState(cm), query);
cm.execCommand(cmd);
} else if (cmd == "find" || cmd == "findPersistent") {
CodeMirror.e_stop(event);
searchNext(query, event);
}
}); });
}); if (immediate && q) {
startSearch(cm, state, q);
findNext(cm, rev);
}
} else {
dialog(cm, queryDialog, "Search for:", q, function(query) {
if (query && !state.query) cm.operation(function() {
startSearch(cm, state, query);
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
});
});
}
} }
function findNext(cm, rev) {cm.operation(function() {
function findNext(cm, rev, callback) {cm.operation(function() {
var state = getSearchState(cm); var state = getSearchState(cm);
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
if (!cursor.find(rev)) { if (!cursor.find(rev)) {
@@ -83,37 +172,50 @@
if (!cursor.find(rev)) return; if (!cursor.find(rev)) return;
} }
cm.setSelection(cursor.from(), cursor.to()); cm.setSelection(cursor.from(), cursor.to());
cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
state.posFrom = cursor.from(); state.posTo = cursor.to(); state.posFrom = cursor.from(); state.posTo = cursor.to();
if (callback) callback(cursor.from(), cursor.to())
});} });}
function clearSearch(cm) {cm.operation(function() { function clearSearch(cm) {cm.operation(function() {
var state = getSearchState(cm); var state = getSearchState(cm);
state.lastQuery = state.query;
if (!state.query) return; if (!state.query) return;
state.query = null; state.query = state.queryText = null;
cm.removeOverlay(state.overlay); cm.removeOverlay(state.overlay);
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
});} });}
var replaceQueryDialog = var replaceQueryDialog =
'Replace: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>'; ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
var replacementQueryDialog = 'With: <input type="text" style="width: 10em"/>'; var replacementQueryDialog = '<span class="CodeMirror-search-label">With:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>"; var doReplaceConfirm = '<span class="CodeMirror-search-label">Replace?</span> <button>Yes</button> <button>No</button> <button>All</button> <button>Stop</button>';
function replaceAll(cm, query, text) {
cm.operation(function() {
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
} else cursor.replace(text);
}
});
}
function replace(cm, all) { function replace(cm, all) {
dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) { if (cm.getOption("readOnly")) return;
var query = cm.getSelection() || getSearchState(cm).lastQuery;
var dialogText = '<span class="CodeMirror-search-label">' + (all ? 'Replace all:' : 'Replace:') + '</span>';
dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) {
if (!query) return; if (!query) return;
query = parseQuery(query); query = parseQuery(query);
dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) { dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
text = parseString(text)
if (all) { if (all) {
cm.operation(function() { replaceAll(cm, query, text)
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/, function(_, i) {return match[i];}));
} else cursor.replace(text);
}
});
} else { } else {
clearSearch(cm); clearSearch(cm);
var cursor = getSearchCursor(cm, query, cm.getCursor()); var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
var advance = function() { var advance = function() {
var start = cursor.from(), match; var start = cursor.from(), match;
if (!(match = cursor.findNext())) { if (!(match = cursor.findNext())) {
@@ -124,11 +226,12 @@
cm.setSelection(cursor.from(), cursor.to()); cm.setSelection(cursor.from(), cursor.to());
cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
confirmDialog(cm, doReplaceConfirm, "Replace?", confirmDialog(cm, doReplaceConfirm, "Replace?",
[function() {doReplace(match);}, advance]); [function() {doReplace(match);}, advance,
function() {replaceAll(cm, query, text)}]);
}; };
var doReplace = function(match) { var doReplace = function(match) {
cursor.replace(typeof query == "string" ? text : cursor.replace(typeof query == "string" ? text :
text.replace(/\$(\d)/, function(_, i) {return match[i];})); text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
advance(); advance();
}; };
advance(); advance();
@@ -138,9 +241,12 @@
} }
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);}; CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);};
CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);};
CodeMirror.commands.findNext = doSearch; CodeMirror.commands.findNext = doSearch;
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
CodeMirror.commands.clearSearch = clearSearch; CodeMirror.commands.clearSearch = clearSearch;
CodeMirror.commands.replace = replace; CodeMirror.commands.replace = replace;
CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);}; CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
})(); });

View File

@@ -1,4 +1,15 @@
(function(){ // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
var Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos;
function SearchCursor(doc, query, pos, caseFold) { function SearchCursor(doc, query, pos, caseFold) {
@@ -96,7 +107,7 @@
var from = Pos(pos.line, cut); var from = Pos(pos.line, cut);
for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln) for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)
if (target[i] != fold(doc.getLine(ln))) return; if (target[i] != fold(doc.getLine(ln))) return;
if (doc.getLine(ln).slice(0, origTarget[last].length) != target[last]) return; if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return;
return {from: from, to: Pos(ln, origTarget[last].length)}; return {from: from, to: Pos(ln, origTarget[last].length)};
} }
}; };
@@ -137,10 +148,10 @@
from: function() {if (this.atOccurrence) return this.pos.from;}, from: function() {if (this.atOccurrence) return this.pos.from;},
to: function() {if (this.atOccurrence) return this.pos.to;}, to: function() {if (this.atOccurrence) return this.pos.to;},
replace: function(newText) { replace: function(newText, origin) {
if (!this.atOccurrence) return; if (!this.atOccurrence) return;
var lines = CodeMirror.splitLines(newText); var lines = CodeMirror.splitLines(newText);
this.doc.replaceRange(lines, this.pos.from, this.pos.to); this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin);
this.pos.to = Pos(this.pos.from.line + lines.length - 1, this.pos.to = Pos(this.pos.from.line + lines.length - 1,
lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)); lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));
} }
@@ -164,4 +175,15 @@
CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
return new SearchCursor(this, query, pos, caseFold); return new SearchCursor(this, query, pos, caseFold);
}); });
})();
CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
var ranges = [];
var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold);
while (cur.findNext()) {
if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break;
ranges.push({anchor: cur.from(), head: cur.to()});
}
if (ranges.length)
this.setSelections(ranges, 0);
});
});

View File

@@ -1,45 +1,72 @@
// Because sometimes you need to style the cursor's line. // CodeMirror, copyright (c) by Marijn Haverbeke and others
// // Distributed under an MIT license: http://codemirror.net/LICENSE
// Adds an option 'styleActiveLine' which, when enabled, gives the
// active line's wrapping <div> the CSS class "CodeMirror-activeline",
// and gives its background <div> the class "CodeMirror-activeline-background".
(function() { (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) {
"use strict"; "use strict";
var WRAP_CLASS = "CodeMirror-activeline"; var WRAP_CLASS = "CodeMirror-activeline";
var BACK_CLASS = "CodeMirror-activeline-background"; var BACK_CLASS = "CodeMirror-activeline-background";
var GUTT_CLASS = "CodeMirror-activeline-gutter";
CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
var prev = old && old != CodeMirror.Init; var prev = old == CodeMirror.Init ? false : old;
if (val && !prev) { if (val == prev) return
updateActiveLine(cm, cm.getCursor().line); if (prev) {
cm.on("beforeSelectionChange", selectionChange);
} else if (!val && prev) {
cm.off("beforeSelectionChange", selectionChange); cm.off("beforeSelectionChange", selectionChange);
clearActiveLine(cm); clearActiveLines(cm);
delete cm.state.activeLine; delete cm.state.activeLines;
}
if (val) {
cm.state.activeLines = [];
updateActiveLines(cm, cm.listSelections());
cm.on("beforeSelectionChange", selectionChange);
} }
}); });
function clearActiveLine(cm) { function clearActiveLines(cm) {
if ("activeLine" in cm.state) { for (var i = 0; i < cm.state.activeLines.length; i++) {
cm.removeLineClass(cm.state.activeLine, "wrap", WRAP_CLASS); cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
cm.removeLineClass(cm.state.activeLine, "background", BACK_CLASS); cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS);
} }
} }
function updateActiveLine(cm, selectedLine) { function sameArray(a, b) {
var line = cm.getLineHandleVisualStart(selectedLine); if (a.length != b.length) return false;
if (cm.state.activeLine == line) return; for (var i = 0; i < a.length; i++)
if (a[i] != b[i]) return false;
return true;
}
function updateActiveLines(cm, ranges) {
var active = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
var option = cm.getOption("styleActiveLine");
if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty())
continue
var line = cm.getLineHandleVisualStart(range.head.line);
if (active[active.length - 1] != line) active.push(line);
}
if (sameArray(cm.state.activeLines, active)) return;
cm.operation(function() { cm.operation(function() {
clearActiveLine(cm); clearActiveLines(cm);
cm.addLineClass(line, "wrap", WRAP_CLASS); for (var i = 0; i < active.length; i++) {
cm.addLineClass(line, "background", BACK_CLASS); cm.addLineClass(active[i], "wrap", WRAP_CLASS);
cm.state.activeLine = line; cm.addLineClass(active[i], "background", BACK_CLASS);
cm.addLineClass(active[i], "gutter", GUTT_CLASS);
}
cm.state.activeLines = active;
}); });
} }
function selectionChange(cm, sel) { function selectionChange(cm, sel) {
updateActiveLine(cm, sel.head.line); updateActiveLines(cm, sel.ranges);
} }
})(); });

View File

@@ -1,10 +1,20 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Because sometimes you need to mark the selected *text*. // Because sometimes you need to mark the selected *text*.
// //
// Adds an option 'styleSelectedText' which, when enabled, gives // Adds an option 'styleSelectedText' which, when enabled, gives
// selected text the CSS class given as option value, or // selected text the CSS class given as option value, or
// "CodeMirror-selectedtext" when the value is not a string. // "CodeMirror-selectedtext" when the value is not a string.
(function() { (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) {
"use strict"; "use strict";
CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
@@ -24,20 +34,18 @@
}); });
function onCursorActivity(cm) { function onCursorActivity(cm) {
cm.operation(function() { update(cm); }); if (cm.state.markedSelection)
cm.operation(function() { update(cm); });
} }
function onChange(cm) { function onChange(cm) {
if (cm.state.markedSelection.length) if (cm.state.markedSelection && cm.state.markedSelection.length)
cm.operation(function() { clear(cm); }); cm.operation(function() { clear(cm); });
} }
var CHUNK_SIZE = 8; var CHUNK_SIZE = 8;
var Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos;
var cmp = CodeMirror.cmpPos;
function cmp(pos1, pos2) {
return pos1.line - pos2.line || pos1.ch - pos2.ch;
}
function coverRange(cm, from, to, addAt) { function coverRange(cm, from, to, addAt) {
if (cmp(from, to) == 0) return; if (cmp(from, to) == 0) return;
@@ -63,13 +71,16 @@
function reset(cm) { function reset(cm) {
clear(cm); clear(cm);
var from = cm.getCursor("start"), to = cm.getCursor("end"); var ranges = cm.listSelections();
coverRange(cm, from, to); for (var i = 0; i < ranges.length; i++)
coverRange(cm, ranges[i].from(), ranges[i].to());
} }
function update(cm) { function update(cm) {
if (!cm.somethingSelected()) return clear(cm);
if (cm.listSelections().length > 1) return reset(cm);
var from = cm.getCursor("start"), to = cm.getCursor("end"); var from = cm.getCursor("start"), to = cm.getCursor("end");
if (cmp(from, to) == 0) return clear(cm);
var array = cm.state.markedSelection; var array = cm.state.markedSelection;
if (!array.length) return coverRange(cm, from, to); if (!array.length) return coverRange(cm, from, to);
@@ -105,4 +116,4 @@
} }
} }
} }
})(); });

View File

@@ -0,0 +1,98 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.defineOption("selectionPointer", false, function(cm, val) {
var data = cm.state.selectionPointer;
if (data) {
CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove);
CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout);
CodeMirror.off(window, "scroll", data.windowScroll);
cm.off("cursorActivity", reset);
cm.off("scroll", reset);
cm.state.selectionPointer = null;
cm.display.lineDiv.style.cursor = "";
}
if (val) {
data = cm.state.selectionPointer = {
value: typeof val == "string" ? val : "default",
mousemove: function(event) { mousemove(cm, event); },
mouseout: function(event) { mouseout(cm, event); },
windowScroll: function() { reset(cm); },
rects: null,
mouseX: null, mouseY: null,
willUpdate: false
};
CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove);
CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout);
CodeMirror.on(window, "scroll", data.windowScroll);
cm.on("cursorActivity", reset);
cm.on("scroll", reset);
}
});
function mousemove(cm, event) {
var data = cm.state.selectionPointer;
if (event.buttons == null ? event.which : event.buttons) {
data.mouseX = data.mouseY = null;
} else {
data.mouseX = event.clientX;
data.mouseY = event.clientY;
}
scheduleUpdate(cm);
}
function mouseout(cm, event) {
if (!cm.getWrapperElement().contains(event.relatedTarget)) {
var data = cm.state.selectionPointer;
data.mouseX = data.mouseY = null;
scheduleUpdate(cm);
}
}
function reset(cm) {
cm.state.selectionPointer.rects = null;
scheduleUpdate(cm);
}
function scheduleUpdate(cm) {
if (!cm.state.selectionPointer.willUpdate) {
cm.state.selectionPointer.willUpdate = true;
setTimeout(function() {
update(cm);
cm.state.selectionPointer.willUpdate = false;
}, 50);
}
}
function update(cm) {
var data = cm.state.selectionPointer;
if (!data) return;
if (data.rects == null && data.mouseX != null) {
data.rects = [];
if (cm.somethingSelected()) {
for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling)
data.rects.push(sel.getBoundingClientRect());
}
}
var inside = false;
if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) {
var rect = data.rects[i];
if (rect.left <= data.mouseX && rect.right >= data.mouseX &&
rect.top <= data.mouseY && rect.bottom >= data.mouseY)
inside = true;
}
var cursor = inside ? data.value : "";
if (cm.display.lineDiv.style.cursor != cursor)
cm.display.lineDiv.style.cursor = cursor;
}
});

View File

@@ -1,6 +1,7 @@
.CodeMirror-Tern-completion { .CodeMirror-Tern-completion {
padding-left: 22px; padding-left: 22px;
position: relative; position: relative;
line-height: 1.5;
} }
.CodeMirror-Tern-completion:before { .CodeMirror-Tern-completion:before {
position: absolute; position: absolute;
@@ -76,6 +77,7 @@
.CodeMirror-Tern-hint-doc { .CodeMirror-Tern-hint-doc {
max-width: 25em; max-width: 25em;
margin-top: -3px;
} }
.CodeMirror-Tern-fname { color: black; } .CodeMirror-Tern-fname { color: black; }

View File

@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Glue code between CodeMirror and Tern. // Glue code between CodeMirror and Tern.
// //
// Create a CodeMirror.TernServer to wrap an actual Tern server, // Create a CodeMirror.TernServer to wrap an actual Tern server,
@@ -14,7 +17,7 @@
// indicate that a file is not available. // indicate that a file is not available.
// * fileFilter: A function(value, docName, doc) that will be applied // * fileFilter: A function(value, docName, doc) that will be applied
// to documents before passing them on to Tern. // to documents before passing them on to Tern.
// * switchToDoc: A function(name) that should, when providing a // * switchToDoc: A function(name, doc) that should, when providing a
// multi-file view, switch the view or focus to the named file. // multi-file view, switch the view or focus to the named file.
// * showError: A function(editor, message) that can be used to // * showError: A function(editor, message) that can be used to
// override the way errors are displayed. // override the way errors are displayed.
@@ -40,7 +43,14 @@
// load. Or, if you minified those into a single script and included // load. Or, if you minified those into a single script and included
// them in the workerScript, simply leave this undefined. // them in the workerScript, simply leave this undefined.
(function() { (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) {
"use strict"; "use strict";
// declare global: tern // declare global: tern
@@ -49,6 +59,7 @@
this.options = options || {}; this.options = options || {};
var plugins = this.options.plugins || (this.options.plugins = {}); var plugins = this.options.plugins || (this.options.plugins = {});
if (!plugins.doc_comment) plugins.doc_comment = true; if (!plugins.doc_comment) plugins.doc_comment = true;
this.docs = Object.create(null);
if (this.options.useWorker) { if (this.options.useWorker) {
this.server = new WorkerServer(this); this.server = new WorkerServer(this);
} else { } else {
@@ -59,12 +70,14 @@
plugins: plugins plugins: plugins
}); });
} }
this.docs = Object.create(null);
this.trackChange = function(doc, change) { trackChange(self, doc, change); }; this.trackChange = function(doc, change) { trackChange(self, doc, change); };
this.cachedArgHints = null; this.cachedArgHints = null;
this.activeArgHints = null; this.activeArgHints = null;
this.jumpStack = []; this.jumpStack = [];
this.getHint = function(cm, c) { return hint(self, cm, c); };
this.getHint.async = true;
}; };
CodeMirror.TernServer.prototype = { CodeMirror.TernServer.prototype = {
@@ -75,28 +88,27 @@
return this.docs[name] = data; return this.docs[name] = data;
}, },
delDoc: function(name) { delDoc: function(id) {
var found = this.docs[name]; var found = resolveDoc(this, id);
if (!found) return; if (!found) return;
CodeMirror.off(found.doc, "change", this.trackChange); CodeMirror.off(found.doc, "change", this.trackChange);
delete this.docs[name]; delete this.docs[found.name];
this.server.delFile(name); this.server.delFile(found.name);
}, },
hideDoc: function(name) { hideDoc: function(id) {
closeArgHints(this); closeArgHints(this);
var found = this.docs[name]; var found = resolveDoc(this, id);
if (found && found.changed) sendDoc(this, found); if (found && found.changed) sendDoc(this, found);
}, },
complete: function(cm) { complete: function(cm) {
var self = this; cm.showHint({hint: this.getHint});
CodeMirror.showHint(cm, function(cm, c) { return hint(self, cm, c); }, {async: true});
}, },
getHint: function(cm, c) { return hint(this, cm, c); }, showType: function(cm, pos, c) { showContextInfo(this, cm, pos, "type", c); },
showType: function(cm, pos) { showType(this, cm, pos); }, showDocs: function(cm, pos, c) { showContextInfo(this, cm, pos, "documentation", c); },
updateArgHints: function(cm) { updateArgHints(this, cm); }, updateArgHints: function(cm) { updateArgHints(this, cm); },
@@ -106,16 +118,28 @@
rename: function(cm) { rename(this, cm); }, rename: function(cm) { rename(this, cm); },
selectName: function(cm) { selectName(this, cm); },
request: function (cm, query, c, pos) { request: function (cm, query, c, pos) {
var self = this; var self = this;
var doc = findDoc(this, cm.getDoc()); var doc = findDoc(this, cm.getDoc());
var request = buildRequest(this, doc, query, pos); var request = buildRequest(this, doc, query, pos);
var extraOptions = request.query && this.options.queryOptions && this.options.queryOptions[request.query.type]
if (extraOptions) for (var prop in extraOptions) request.query[prop] = extraOptions[prop];
this.server.request(request, function (error, data) { this.server.request(request, function (error, data) {
if (!error && self.options.responseFilter) if (!error && self.options.responseFilter)
data = self.options.responseFilter(doc, query, request, error, data); data = self.options.responseFilter(doc, query, request, error, data);
c(error, data); c(error, data);
}); });
},
destroy: function () {
closeArgHints(this)
if (this.worker) {
this.worker.terminate();
this.worker = null;
}
} }
}; };
@@ -145,11 +169,17 @@
return ts.addDoc(name, doc); return ts.addDoc(name, doc);
} }
function resolveDoc(ts, id) {
if (typeof id == "string") return ts.docs[id];
if (id instanceof CodeMirror) id = id.getDoc();
if (id instanceof CodeMirror.Doc) return findDoc(ts, id);
}
function trackChange(ts, doc, change) { function trackChange(ts, doc, change) {
var data = findDoc(ts, doc); var data = findDoc(ts, doc);
var argHints = ts.cachedArgHints; var argHints = ts.cachedArgHints;
if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0) if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) >= 0)
ts.cachedArgHints = null; ts.cachedArgHints = null;
var changed = data.changed; var changed = data.changed;
@@ -167,7 +197,7 @@
function sendDoc(ts, doc) { function sendDoc(ts, doc) {
ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) { ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) {
if (error) console.error(error); if (error) window.console.error(error);
else doc.changed = null; else doc.changed = null;
}); });
} }
@@ -187,7 +217,7 @@
var completion = data.completions[i], className = typeToIcon(completion.type); var completion = data.completions[i], className = typeToIcon(completion.type);
if (data.guess) className += " " + cls + "guess"; if (data.guess) className += " " + cls + "guess";
completions.push({text: completion.name + after, completions.push({text: completion.name + after,
displayText: completion.name, displayText: completion.displayName || completion.name,
className: className, className: className,
data: completion}); data: completion});
} }
@@ -221,8 +251,8 @@
// Type queries // Type queries
function showType(ts, cm, pos) { function showContextInfo(ts, cm, pos, queryName, c) {
ts.request(cm, "type", function(error, data) { ts.request(cm, queryName, function(error, data) {
if (error) return showError(ts, cm, error); if (error) return showError(ts, cm, error);
if (ts.options.typeTip) { if (ts.options.typeTip) {
var tip = ts.options.typeTip(data); var tip = ts.options.typeTip(data);
@@ -232,10 +262,13 @@
tip.appendChild(document.createTextNode(" — " + data.doc)); tip.appendChild(document.createTextNode(" — " + data.doc));
if (data.url) { if (data.url) {
tip.appendChild(document.createTextNode(" ")); tip.appendChild(document.createTextNode(" "));
tip.appendChild(elt("a", null, "[docs]")).href = data.url; var child = tip.appendChild(elt("a", null, "[docs]"));
child.href = data.url;
child.target = "_blank";
} }
} }
tempTooltip(cm, tip); tempTooltip(cm, tip, ts);
if (c) c();
}, pos); }, pos);
} }
@@ -273,7 +306,7 @@
ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) { ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) {
if (error || !data.type || !(/^fn\(/).test(data.type)) return; if (error || !data.type || !(/^fn\(/).test(data.type)) return;
ts.cachedArgHints = { ts.cachedArgHints = {
start: pos, start: start,
type: parseFnType(data.type), type: parseFnType(data.type),
name: data.exprName || data.name || "fn", name: data.exprName || data.name || "fn",
guess: data.guess, guess: data.guess,
@@ -372,10 +405,10 @@
} }
function moveTo(ts, curDoc, doc, start, end) { function moveTo(ts, curDoc, doc, start, end) {
doc.doc.setSelection(end, start); doc.doc.setSelection(start, end);
if (curDoc != doc && ts.options.switchToDoc) { if (curDoc != doc && ts.options.switchToDoc) {
closeArgHints(ts); closeArgHints(ts);
ts.options.switchToDoc(doc.name); ts.options.switchToDoc(doc.name, doc.doc);
} }
} }
@@ -412,15 +445,15 @@
function atInterestingExpression(cm) { function atInterestingExpression(cm) {
var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos); var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos);
if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false; if (tok.start < pos.ch && tok.type == "comment") return false;
return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1)); return /[\w)\]]/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
} }
// Variable renaming // Variable renaming
function rename(ts, cm) { function rename(ts, cm) {
var token = cm.getTokenAt(cm.getCursor()); var token = cm.getTokenAt(cm.getCursor());
if (!/\w/.test(token.string)) showError(ts, cm, "Not at a variable"); if (!/\w/.test(token.string)) return showError(ts, cm, "Not at a variable");
dialog(cm, "New name for " + token.string, function(newName) { dialog(cm, "New name for " + token.string, function(newName) {
ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) { ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) {
if (error) return showError(ts, cm, error); if (error) return showError(ts, cm, error);
@@ -429,6 +462,24 @@
}); });
} }
function selectName(ts, cm) {
var name = findDoc(ts, cm.doc).name;
ts.request(cm, {type: "refs"}, function(error, data) {
if (error) return showError(ts, cm, error);
var ranges = [], cur = 0;
var curPos = cm.getCursor();
for (var i = 0; i < data.refs.length; i++) {
var ref = data.refs[i];
if (ref.file == name) {
ranges.push({anchor: ref.start, head: ref.end});
if (cmpPos(curPos, ref.start) >= 0 && cmpPos(curPos, ref.end) <= 0)
cur = ranges.length - 1;
}
}
cm.setSelections(ranges, cur);
});
}
var nextChangeOrig = 0; var nextChangeOrig = 0;
function applyChanges(ts, changes) { function applyChanges(ts, changes) {
var perFile = Object.create(null); var perFile = Object.create(null);
@@ -521,7 +572,7 @@
// Generic utilities // Generic utilities
function cmpPos(a, b) { return a.line - b.line || a.ch - b.ch; } var cmpPos = CodeMirror.cmpPos;
function elt(tagname, cls /*, ... elts*/) { function elt(tagname, cls /*, ... elts*/) {
var e = document.createElement(tagname); var e = document.createElement(tagname);
@@ -543,16 +594,34 @@
// Tooltips // Tooltips
function tempTooltip(cm, content) { function tempTooltip(cm, content, ts) {
if (cm.state.ternTooltip) remove(cm.state.ternTooltip);
var where = cm.cursorCoords(); var where = cm.cursorCoords();
var tip = makeTooltip(where.right + 1, where.bottom, content); var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content);
function maybeClear() {
old = true;
if (!mouseOnTip) clear();
}
function clear() { function clear() {
cm.state.ternTooltip = null;
if (!tip.parentNode) return; if (!tip.parentNode) return;
cm.off("cursorActivity", clear); cm.off("cursorActivity", clear);
cm.off('blur', clear);
cm.off('scroll', clear);
fadeOut(tip); fadeOut(tip);
} }
setTimeout(clear, 1700); var mouseOnTip = false, old = false;
CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; });
CodeMirror.on(tip, "mouseout", function(e) {
if (!CodeMirror.contains(tip, e.relatedTarget || e.toElement)) {
if (old) clear();
else mouseOnTip = false;
}
});
setTimeout(maybeClear, ts.options.hintDelay ? ts.options.hintDelay : 1700);
cm.on("cursorActivity", clear); cm.on("cursorActivity", clear);
cm.on('blur', clear);
cm.on('scroll', clear);
} }
function makeTooltip(x, y, content) { function makeTooltip(x, y, content) {
@@ -577,7 +646,7 @@
if (ts.options.showError) if (ts.options.showError)
ts.options.showError(cm, msg); ts.options.showError(cm, msg);
else else
tempTooltip(cm, String(msg)); tempTooltip(cm, String(msg), ts);
} }
function closeArgHints(ts) { function closeArgHints(ts) {
@@ -593,7 +662,7 @@
// Worker wrapper // Worker wrapper
function WorkerServer(ts) { function WorkerServer(ts) {
var worker = new Worker(ts.options.workerScript); var worker = ts.worker = new Worker(ts.options.workerScript);
worker.postMessage({type: "init", worker.postMessage({type: "init",
defs: ts.options.defs, defs: ts.options.defs,
plugins: ts.options.plugins, plugins: ts.options.plugins,
@@ -614,7 +683,7 @@
send({type: "getFile", err: String(err), text: text, id: data.id}); send({type: "getFile", err: String(err), text: text, id: data.id});
}); });
} else if (data.type == "debug") { } else if (data.type == "debug") {
//console.log(data.message); window.console.log(data.message);
} else if (data.id && pending[data.id]) { } else if (data.id && pending[data.id]) {
pending[data.id](data.err, data.body); pending[data.id](data.err, data.body);
delete pending[data.id]; delete pending[data.id];
@@ -629,4 +698,4 @@
this.delFile = function(name) { send({type: "del", name: name}); }; this.delFile = function(name) { send({type: "del", name: name}); };
this.request = function(body, c) { send({type: "req", body: body}, c); }; this.request = function(body, c) { send({type: "req", body: body}, c); };
} }
})(); });

View File

@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// declare global: tern, server // declare global: tern, server
var server; var server;
@@ -36,6 +39,6 @@ function startServer(defs, plugins, scripts) {
}); });
} }
var console = { this.console = {
log: function(v) { postMessage({type: "debug", message: v}); } log: function(v) { postMessage({type: "debug", message: v}); }
}; };

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
var Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos;
@@ -20,13 +30,17 @@
} }
function findBreakPoint(text, column, wrapOn, killTrailingSpace) { function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
for (var at = column; at > 0; --at) var at = column
while (at < text.length && text.charAt(at) == " ") at++
for (; at > 0; --at)
if (wrapOn.test(text.slice(at - 1, at + 1))) break; if (wrapOn.test(text.slice(at - 1, at + 1))) break;
if (at == 0) at = column; for (var first = true;; first = false) {
var endOfText = at; var endOfText = at;
if (killTrailingSpace) if (killTrailingSpace)
while (text.charAt(endOfText - 1) == " ") --endOfText; while (text.charAt(endOfText - 1) == " ") --endOfText;
return {from: endOfText, to: at}; if (endOfText == 0 && first) at = column;
else return {from: endOfText, to: at};
}
} }
function wrapRange(cm, from, to, options) { function wrapRange(cm, from, to, options) {
@@ -76,7 +90,8 @@
if (changes.length) cm.operation(function() { if (changes.length) cm.operation(function() {
for (var i = 0; i < changes.length; ++i) { for (var i = 0; i < changes.length; ++i) {
var change = changes[i]; var change = changes[i];
cm.replaceRange(change.text, change.from, change.to); if (change.text || CodeMirror.cmpPos(change.from, change.to))
cm.replaceRange(change.text, change.from, change.to);
} }
}); });
return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null; return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null;
@@ -89,6 +104,24 @@
return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options); return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options);
}); });
CodeMirror.commands.wrapLines = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections(), at = cm.lastLine() + 1;
for (var i = ranges.length - 1; i >= 0; i--) {
var range = ranges[i], span;
if (range.empty()) {
var para = findParagraph(cm, range.head, {});
span = {from: Pos(para.from, 0), to: Pos(para.to - 1)};
} else {
span = {from: range.from(), to: range.to()};
}
if (span.to.line >= at) continue;
at = span.from.line;
wrapRange(cm, span.from, span.to, {});
}
});
};
CodeMirror.defineExtension("wrapRange", function(from, to, options) { CodeMirror.defineExtension("wrapRange", function(from, to, options) {
return wrapRange(this, from, to, options || {}); return wrapRange(this, from, to, options || {});
}); });
@@ -108,4 +141,4 @@
}); });
return madeChange; return madeChange;
}); });
})(); });

View File

@@ -18,7 +18,7 @@
// Script files are specified without .js ending. Prefixing them with // Script files are specified without .js ending. Prefixing them with
// their full (local) path is optional. So you may say lib/codemirror // their full (local) path is optional. So you may say lib/codemirror
// or mode/xml/xml to be more precise. In fact, even the .js suffix // or mode/xml/xml to be more precise. In fact, even the .js suffix
// may be speficied, if wanted. // may be specified, if wanted.
"use strict"; "use strict";
@@ -68,7 +68,7 @@ walk("mode/");
if (!local && !blob) help(false); if (!local && !blob) help(false);
if (files.length) { if (files.length) {
console.log("Some speficied files were not found: " + console.log("Some specified files were not found: " +
files.map(function(a){return a.name;}).join(", ")); files.map(function(a){return a.name;}).join(", "));
process.exit(1); process.exit(1);
} }

View File

@@ -1,16 +1,3 @@
#!/usr/bin/env node #!/usr/bin/env node
var lint = require("../test/lint/lint"), process.exit(require("../test/lint").ok ? 0 : 1);
path = require("path");
if (process.argv.length > 2) {
lint.checkDir(process.argv[2]);
} else {
process.chdir(path.resolve(__dirname, ".."));
lint.checkDir("lib");
lint.checkDir("mode");
lint.checkDir("addon");
lint.checkDir("keymap");
}
process.exit(lint.success() ? 0 : 1);

View File

@@ -16,26 +16,23 @@ function rewrite(file, f) {
fs.writeFileSync(file, f(fs.readFileSync(file, "utf8")), "utf8"); fs.writeFileSync(file, f(fs.readFileSync(file, "utf8")), "utf8");
} }
rewrite("lib/codemirror.js", function(lib) { rewrite("src/edit/main.js", function(lib) {
return lib.replace(/CodeMirror\.version = "\d+\.\d+\.\d+"/, return lib.replace(/CodeMirror\.version = "\d+\.\d+\.\d+"/,
"CodeMirror.version = \"" + number + "\""); "CodeMirror.version = \"" + number + "\"");
}); });
rewrite("package.json", function(pack) { function rewriteJSON(pack) {
return pack.replace(/"version":"\d+\.\d+\.\d+"/, "\"version\":\"" + number + "\""); return pack.replace(/"version":\s*"\d+\.\d+\.\d+"/, "\"version\": \"" + number + "\"");
}
rewrite("package.json", rewriteJSON);
rewrite("doc/manual.html", function(manual) {
return manual.replace(/>version \d+\.\d+\.\d+<\/span>/, ">version " + number + "</span>");
}); });
if (bumpOnly) process.exit(0); if (bumpOnly) process.exit(0);
child.exec("bash bin/authors.sh", function(){}); child.exec("bash bin/authors.sh", function(){});
var simple = number.slice(0, number.lastIndexOf("."));
rewrite("doc/compress.html", function(cmp) {
return cmp.replace(/<option value="http:\/\/codemirror.net\/">HEAD<\/option>/,
"<option value=\"http://codemirror.net/\">HEAD</option>\n <option value=\"http://marijnhaverbeke.nl/git/codemirror?a=blob_plain;hb=" + number + ";f=\">" + simple + "</option>");
});
rewrite("index.html", function(index) { rewrite("index.html", function(index) {
return index.replace(/<strong>version 3.20<\/strong>/, return index.replace(/\.zip">\d+\.\d+\.\d+<\/a>/,
"<strong>version " + simple + "</strong>"); ".zip\">" + number + "</a>");
}); });

View File

@@ -8,7 +8,7 @@
var fs = require("fs"); var fs = require("fs");
CodeMirror = require("../addon/runmode/runmode.node.js"); var CodeMirror = require("../addon/runmode/runmode.node.js");
require("../mode/meta.js"); require("../mode/meta.js");
var sPos = process.argv.indexOf("-s"); var sPos = process.argv.indexOf("-s");
@@ -17,30 +17,17 @@ if (sPos == -1 || sPos == process.argv.length - 1) {
process.exit(1); process.exit(1);
} }
var lang = process.argv[sPos + 1].toLowerCase(), modeName = lang; var lang = process.argv[sPos + 1].toLowerCase(), modeName = lang;
CodeMirror.modeInfo.forEach(function(info) { var found = CodeMirror.findModeByMIME(lang) || CodeMirror.findModeByName(lang)
if (info.mime == lang) { if (found) {
modeName = info.mode; modeName = found.mode
} else if (info.name.toLowerCase() == lang) { lang = found.mime
modeName = info.mode;
lang = info.mime;
}
});
function ensureMode(name) {
if (CodeMirror.modes[name] || name == "null") return;
try {
require("../mode/" + name + "/" + name + ".js");
} catch(e) {
console.error("Could not load mode " + name + ".");
process.exit(1);
}
var obj = CodeMirror.modes[name];
if (obj.dependencies) obj.dependencies.forEach(ensureMode);
} }
ensureMode(modeName);
if (!CodeMirror.modes[modeName])
require("../mode/" + modeName + "/" + modeName + ".js");
function esc(str) { function esc(str) {
return str.replace(/[<&]/, function(ch) { return ch == "&" ? "&amp;" : "&lt;"; }); return str.replace(/[<&]/g, function(ch) { return ch == "&" ? "&amp;" : "&lt;"; });
} }
var code = fs.readFileSync("/dev/stdin", "utf8"); var code = fs.readFileSync("/dev/stdin", "utf8");

View File

@@ -0,0 +1,35 @@
"use strict"
let version = process.argv[2]
let auth = process.argv[3]
if (!auth) {
console.log("Usage: upload-release.js [TAG] [github-user:password]")
process.exit(1)
}
require('child_process').exec("git --no-pager show -s --format='%s' " + version, (error, stdout) => {
if (error) throw error
let message = stdout.split("\n").slice(2)
message = message.slice(0, message.indexOf("-----BEGIN PGP SIGNATURE-----")).join("\n")
let req = require("https").request({
host: "api.github.com",
auth: auth,
headers: {"user-agent": "Release uploader"},
path: "/repos/codemirror/codemirror/releases",
method: "POST"
}, res => {
if (res.statusCode >= 300) {
console.error(res.statusMessage)
res.on("data", d => console.log(d.toString()))
res.on("end", process.exit(1))
}
})
req.write(JSON.stringify({
tag_name: version,
name: version,
body: message
}))
req.end()
})

View File

@@ -1,15 +0,0 @@
{
"name": "CodeMirror",
"main": ["lib/codemirror.js", "lib/codemirror.css"],
"ignore": [
"**/.*",
"node_modules",
"components",
"bin",
"demo",
"doc",
"test",
"index.html",
"package.json"
]
}

View File

@@ -21,12 +21,12 @@
</style> </style>
<div id=nav> <div id=nav>
<a href="http://codemirror.net"><img id=logo src="doc/logo.png"></a> <a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="doc/logo.png"></a>
<ul> <ul>
<li><a class=active data-default="true" href="#description">Home</a> <li><a class=active data-default="true" href="#description">Home</a>
<li><a href="doc/manual.html">Manual</a> <li><a href="doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a> <li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul> </ul>
<ul> <ul>
<li><a href="#features">Features</a> <li><a href="#features">Features</a>
@@ -40,8 +40,8 @@
<section id=description class=first> <section id=description class=first>
<p><strong>CodeMirror</strong> is a versatile text editor <p><strong>CodeMirror</strong> is a versatile text editor
implemented in JavaScript for the browser. It is specialized for implemented in JavaScript for the browser. It is specialized for
editing code, and comes with a number of language modes and addons editing code, and comes with a number of <a href="mode/index.html">language modes</a> and <a href="doc/manual.html#addons">addons</a>
that implement more advanced editing functionaly.</p> that implement more advanced editing functionality.</p>
<p>A rich <a href="doc/manual.html#api">programming API</a> and a <p>A rich <a href="doc/manual.html#api">programming API</a> and a
CSS <a href="doc/manual.html#styling">theming</a> system are CSS <a href="doc/manual.html#styling">theming</a> system are
@@ -57,7 +57,7 @@
<script src="lib/codemirror.js"></script> <script src="lib/codemirror.js"></script>
<script> <script>
var editor = CodeMirror.fromTextArea(myTextarea, { var editor = CodeMirror.fromTextArea(myTextarea, {
mode: "text/html" lineNumbers: true
}); });
</script></textarea> </script></textarea>
<select id="demolist" onchange="document.location = this.options[this.selectedIndex].value;"> <select id="demolist" onchange="document.location = this.options[this.selectedIndex].value;">
@@ -71,9 +71,11 @@
<option value="demo/search.html">Search interface</option> <option value="demo/search.html">Search interface</option>
<option value="demo/vim.html">Vim bindings</option> <option value="demo/vim.html">Vim bindings</option>
<option value="demo/emacs.html">Emacs bindings</option> <option value="demo/emacs.html">Emacs bindings</option>
<option value="demo/sublime.html">Sublime Text bindings</option>
<option value="demo/tern.html">Tern integration</option> <option value="demo/tern.html">Tern integration</option>
<option value="demo/merge.html">Merge/diff interface</option> <option value="demo/merge.html">Merge/diff interface</option>
<option value="demo/fullscreen.html">Full-screen editor</option> <option value="demo/fullscreen.html">Full-screen editor</option>
<option value="demo/simplescrollbars.html">Custom scrollbars</option>
</select></form> </select></form>
<script> <script>
var editor = CodeMirror.fromTextArea(document.getElementById("demotext"), { var editor = CodeMirror.fromTextArea(document.getElementById("demotext"), {
@@ -82,46 +84,47 @@
matchBrackets: true matchBrackets: true
}); });
</script> </script>
<div style="position: relative; margin: 1em 0;">
<a class="bigbutton left" href="http://codemirror.net/codemirror.zip">DOWNLOAD LATEST RELEASE</a> <div class=actions>
<div><strong>version 3.21</strong> (<a href="doc/releases.html">Release notes</a>)</div> <div class=actionspicture>
<div>or use the <a href="doc/compress.html">minification helper</a></div> <img src="doc/yinyang.png" class=yinyang>
<div style="position: absolute; top: 0; right: 0; text-align: right"> <div class="actionlink download">
<span class="bigbutton right" onclick="document.getElementById('paypal').submit();">DONATE WITH PAYPAL</span> <a href="http://codemirror.net/codemirror.zip">DOWNLOAD</a>
<div style="position: relative">
or <span onclick="document.getElementById('bankinfo').style.display = 'block';" class=quasilink>Bank</span>,
<a href="https://www.gittip.com/marijnh">Gittip</a>,
<a href="https://flattr.com/profile/marijnh">Flattr</a><br>
<div id=bankinfo>
<span id=bankinfo_close onclick="document.getElementById('bankinfo').style.display = '';">×</span>
Bank: <i>Rabobank</i><br/>
Country: <i>Netherlands</i><br/>
SWIFT: <i>RABONL2U</i><br/>
Account: <i>147850770</i><br/>
Name: <i>Marijn Haverbeke</i><br/>
IBAN: <i>NL26 RABO 0147 8507 70</i>
</div>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="paypal">
<input type="hidden" name="cmd" value="_s-xclick"/>
<input type="hidden" name="hosted_button_id" value="3FVHS5FGUY7CC"/>
</form>
</div> </div>
<div> <div class="actionlink fund">
Purchase <a href="http://codemirror.com">commercial support</a> <a href="https://marijnhaverbeke.nl/fund/">FUND</a>
</div> </div>
</div> </div>
<div class=actionsleft>
Get the current version: <a href="http://codemirror.net/codemirror.zip">5.25.2</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>.
</div>
<div class=actionsright>
Software needs maintenance,<br>
maintainers need to subsist.<br>
Current funding status = <img src="https://marijnhaverbeke.nl/fund/status_s.png" title="Current maintainer happiness" style="vertical-align: middle; height: 16px; width: 16px"><br>
You can help <a href="https://marijnhaverbeke.nl/fund/" title="Set up a monthly contribution">per month</a> or
<a title="Donate with PayPal" href="javascript:document.getElementById('paypal').submit();">once</a>.
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="paypal">
<input type="hidden" name="cmd" value="_s-xclick"/>
<input type="hidden" name="hosted_button_id" value="3FVHS5FGUY7CC"/>
</form>
</div>
</div> </div>
</section> </section>
<section id=features> <section id=features>
<h2>Features</h2> <h2>Features</h2>
<ul> <ul>
<li>Support for <a href="mode/index.html">over 60 languages</a> out of the box <li>Support for <a href="mode/index.html">over 100 languages</a> out of the box
<li>A powerful, <a href="mode/htmlmixed/index.html">composable</a> language mode <a href="doc/manual.html#modeapi">system</a> <li>A powerful, <a href="mode/htmlmixed/index.html">composable</a> language mode <a href="doc/manual.html#modeapi">system</a>
<li><a href="doc/manual.html#addon_show-hint">Autocompletion</a> (<a href="demo/xmlcomplete.html">XML</a>) <li><a href="doc/manual.html#addon_show-hint">Autocompletion</a> (<a href="demo/xmlcomplete.html">XML</a>)
<li><a href="doc/manual.html#addon_foldcode">Code folding</a> <li><a href="doc/manual.html#addon_foldcode">Code folding</a>
<li><a href="doc/manual.html#option_extraKeys">Configurable</a> keybindings <li><a href="doc/manual.html#option_extraKeys">Configurable</a> keybindings
<li><a href="demo/vim.html">Vim</a> and <a href="demo/emacs.html">Emacs</a> bindings <li><a href="demo/vim.html">Vim</a>, <a href="demo/emacs.html">Emacs</a>, and <a href="demo/sublime.html">Sublime Text</a> bindings
<li><a href="doc/manual.html#addon_search">Search and replace</a> interface <li><a href="doc/manual.html#addon_search">Search and replace</a> interface
<li><a href="doc/manual.html#addon_matchbrackets">Bracket</a> and <a href="doc/manual.html#addon_matchtags">tag</a> matching <li><a href="doc/manual.html#addon_matchbrackets">Bracket</a> and <a href="doc/manual.html#addon_matchtags">tag</a> matching
<li>Support for <a href="demo/buffers.html">split views</a> <li>Support for <a href="demo/buffers.html">split views</a>
@@ -141,15 +144,17 @@
<h2>Community</h2> <h2>Community</h2>
<p>CodeMirror is an open-source project shared under <p>CodeMirror is an open-source project shared under
an <a href="LICENSE">MIT license</a>. It is the editor used in an <a href="LICENSE">MIT license</a>. It is the editor used in the
<a href="http://www.chris-granger.com/2012/04/12/light-table---a-new-ide-concept/">Light dev tools for
<a href="https://hacks.mozilla.org/2013/11/firefox-developer-tools-episode-27-edit-as-html-codemirror-more/">Firefox</a>,
<a href="https://developers.google.com/chrome-developer-tools/">Chrome</a>,
and <a href="https://developer.apple.com/safari/tools/">Safari</a>, in <a href="http://www.lighttable.com/">Light
Table</a>, <a href="http://brackets.io/">Adobe Table</a>, <a href="http://brackets.io/">Adobe
Brackets</a>, <a href="https://script.google.com/">Google Apps Brackets</a>, <a href="http://blog.bitbucket.org/2013/05/14/edit-your-code-in-the-cloud-with-bitbucket/">Bitbucket</a>,
Script</a>, <a href="http://blog.bitbucket.org/2013/05/14/edit-your-code-in-the-cloud-with-bitbucket/">Bitbucket</a>,
and <a href="doc/realworld.html">many other projects</a>.</p> and <a href="doc/realworld.html">many other projects</a>.</p>
<p>Development and bug tracking happens <p>Development and bug tracking happens
on <a href="https://github.com/marijnh/CodeMirror/">github</a> on <a href="https://github.com/codemirror/CodeMirror/">github</a>
(<a href="http://marijnhaverbeke.nl/git/codemirror">alternate git (<a href="http://marijnhaverbeke.nl/git/codemirror">alternate git
repository</a>). repository</a>).
Please <a href="http://codemirror.net/doc/reporting.html">read these Please <a href="http://codemirror.net/doc/reporting.html">read these
@@ -158,35 +163,38 @@
license that CodeMirror uses.</p> license that CodeMirror uses.</p>
<p>Discussion around the project is done on <p>Discussion around the project is done on
a <a href="http://groups.google.com/group/codemirror">mailing list</a>. a <a href="https://discuss.codemirror.net">discussion forum</a>.
There is also Announcements related to the project, such as new versions, are
the <a href="http://groups.google.com/group/codemirror-announce">codemirror-announce</a> posted in the
list, which is only used for major announcements (such as new forum's <a href="https://discuss.codemirror.net/c/announce">"announce"</a>
versions). If needed, you can category. If needed, you can
contact <a href="mailto:marijnh@gmail.com">the maintainer</a> contact <a href="mailto:marijnh@gmail.com">the maintainer</a>
directly.</p> directly. We aim to be an inclusive, welcoming community. To make
that explicit, we have
a <a href="http://contributor-covenant.org/version/1/1/0/">code of
conduct</a> that applies to communication around the project.</p>
<p>A list of CodeMirror-related software that is not part of the <p>A list of CodeMirror-related software that is not part of the
main distribution is maintained main distribution is maintained
on <a href="https://github.com/marijnh/CodeMirror/wiki/CodeMirror-addons">our on <a href="https://github.com/codemirror/CodeMirror/wiki/CodeMirror-addons">our
wiki</a>. Feel free to add your project.</p> wiki</a>. Feel free to add your project.</p>
</section> </section>
<section id=browsersupport> <section id=browsersupport>
<h2>Browser support</h2> <h2>Browser support</h2>
<p>The <em>desktop</em> versions of the following browsers, <p>The <em>desktop</em> versions of the following browsers,
in <em>standards mode</em> (HTML5 <code>&lt;!doctype html></code> in <em>standards mode</em> (HTML5 <code>&lt;!doctype html></code>
recommended) are supported:</p> recommended) are supported:</p>
<table style="margin-bottom: 1em"> <table style="margin-bottom: 1em">
<tr><th>Firefox</th><td>version 3 and up</td></tr> <tr><th>Firefox</th><td>version 4 and up</td></tr>
<tr><th>Chrome</th><td>any version</td></tr> <tr><th>Chrome</th><td>any version</td></tr>
<tr><th>Safari</th><td>version 5.2 and up</td></tr> <tr><th>Safari</th><td>version 5.2 and up</td></tr>
<tr><th style="padding-right: 1em;">Internet Explorer</th><td>version 8 and up</td></tr> <tr><th style="padding-right: 1em;">Internet Explorer</th><td>version 8 and up</td></tr>
<tr><th>Opera</th><td>version 9 and up</td></tr> <tr><th>Opera</th><td>version 9 and up</td></tr>
</table> </table>
<p>Modern mobile browsers tend to partly work. Bug reports and <p>Support for modern mobile browsers is experimental. Recent
patches for mobile support are welcome, but the maintainer does not versions of the iOS browser and Chrome on Android should work
have the time or budget to actually work on it himself.</p> pretty well.</p>
</section> </section>
</article> </article>

View File

@@ -1,4 +1,14 @@
(function() { // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict"; "use strict";
var Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos;
@@ -122,8 +132,8 @@
}; };
} }
function findEnd(cm, by, dir) { function findEnd(cm, pos, by, dir) {
var pos = cm.getCursor(), prefix = getPrefix(cm); var prefix = getPrefix(cm);
if (prefix < 0) { dir = -dir; prefix = -prefix; } if (prefix < 0) { dir = -dir; prefix = -prefix; }
for (var i = 0; i < prefix; ++i) { for (var i = 0; i < prefix; ++i) {
var newPos = by(cm, pos, dir); var newPos = by(cm, pos, dir);
@@ -135,14 +145,31 @@
function move(by, dir) { function move(by, dir) {
var f = function(cm) { var f = function(cm) {
cm.extendSelection(findEnd(cm, by, dir)); cm.extendSelection(findEnd(cm, cm.getCursor(), by, dir));
}; };
f.motion = true; f.motion = true;
return f; return f;
} }
function killTo(cm, by, dir) { function killTo(cm, by, dir) {
kill(cm, cm.getCursor(), findEnd(cm, by, dir), true); var selections = cm.listSelections(), cursor;
var i = selections.length;
while (i--) {
cursor = selections[i].head;
kill(cm, cursor, findEnd(cm, cursor, by, dir), true);
}
}
function killRegion(cm) {
if (cm.somethingSelected()) {
var selections = cm.listSelections(), selection;
var i = selections.length;
while (i--) {
selection = selections[i];
kill(cm, selection.anchor, selection.head);
}
return true;
}
} }
function addPrefix(cm, digit) { function addPrefix(cm, digit) {
@@ -174,7 +201,7 @@
if (dup > 1 && event.origin == "+input") { if (dup > 1 && event.origin == "+input") {
var one = event.text.join("\n"), txt = ""; var one = event.text.join("\n"), txt = "";
for (var i = 1; i < dup; ++i) txt += one; for (var i = 1; i < dup; ++i) txt += one;
cm.replaceSelection(txt, "end", "+input"); cm.replaceSelection(txt);
} }
} }
@@ -197,7 +224,7 @@
function setMark(cm) { function setMark(cm) {
cm.setCursor(cm.getCursor()); cm.setCursor(cm.getCursor());
cm.setExtending(true); cm.setExtending(!cm.getExtending());
cm.on("change", function() { cm.setExtending(false); }); cm.on("change", function() { cm.setExtending(false); });
} }
@@ -244,9 +271,11 @@
clearMark(cm); clearMark(cm);
} }
CodeMirror.emacs = {kill: kill, killRegion: killRegion, repeated: repeated};
// Actual keymap // Actual keymap
var keyMap = CodeMirror.keyMap.emacs = { var keyMap = CodeMirror.keyMap.emacs = CodeMirror.normalizeKeyMap({
"Ctrl-W": function(cm) {kill(cm, cm.getCursor("start"), cm.getCursor("end"));}, "Ctrl-W": function(cm) {kill(cm, cm.getCursor("start"), cm.getCursor("end"));},
"Ctrl-K": repeated(function(cm) { "Ctrl-K": repeated(function(cm) {
var start = cm.getCursor(), end = cm.clipPos(Pos(start.line)); var start = cm.getCursor(), end = cm.clipPos(Pos(start.line));
@@ -266,16 +295,16 @@
cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste"); cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste");
cm.setSelection(start, cm.getCursor()); cm.setSelection(start, cm.getCursor());
}, },
"Alt-Y": function(cm) {cm.replaceSelection(popFromRing());}, "Alt-Y": function(cm) {cm.replaceSelection(popFromRing(), "around", "paste");},
"Ctrl-Space": setMark, "Ctrl-Shift-2": setMark, "Ctrl-Space": setMark, "Ctrl-Shift-2": setMark,
"Ctrl-F": move(byChar, 1), "Ctrl-B": move(byChar, -1), "Ctrl-F": move(byChar, 1), "Ctrl-B": move(byChar, -1),
"Right": move(byChar, 1), "Left": move(byChar, -1), "Right": move(byChar, 1), "Left": move(byChar, -1),
"Ctrl-D": function(cm) { killTo(cm, byChar, 1); }, "Ctrl-D": function(cm) { killTo(cm, byChar, 1); },
"Delete": function(cm) { killTo(cm, byChar, 1); }, "Delete": function(cm) { killRegion(cm) || killTo(cm, byChar, 1); },
"Ctrl-H": function(cm) { killTo(cm, byChar, -1); }, "Ctrl-H": function(cm) { killTo(cm, byChar, -1); },
"Backspace": function(cm) { killTo(cm, byChar, -1); }, "Backspace": function(cm) { killRegion(cm) || killTo(cm, byChar, -1); },
"Alt-F": move(byWord, 1), "Alt-B": move(byWord, -1), "Alt-F": move(byWord, 1), "Alt-B": move(byWord, -1),
"Alt-D": function(cm) { killTo(cm, byWord, 1); }, "Alt-D": function(cm) { killTo(cm, byWord, 1); },
@@ -299,7 +328,8 @@
"Ctrl-Alt-F": move(byExpr, 1), "Ctrl-Alt-B": move(byExpr, -1), "Ctrl-Alt-F": move(byExpr, 1), "Ctrl-Alt-B": move(byExpr, -1),
"Shift-Ctrl-Alt-2": function(cm) { "Shift-Ctrl-Alt-2": function(cm) {
cm.setSelection(findEnd(cm, byExpr, 1), cm.getCursor()); var cursor = cm.getCursor();
cm.setSelection(findEnd(cm, cursor, byExpr, 1), cursor);
}, },
"Ctrl-Alt-T": function(cm) { "Ctrl-Alt-T": function(cm) {
var leftStart = byExpr(cm, cm.getCursor(), -1), leftEnd = byExpr(cm, leftStart, 1); var leftStart = byExpr(cm, cm.getCursor(), -1), leftEnd = byExpr(cm, leftStart, 1);
@@ -317,13 +347,7 @@
}, },
"Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }), "Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }),
"Ctrl-T": repeated(function(cm) { "Ctrl-T": repeated(function(cm) {
var pos = cm.getCursor(); cm.execCommand("transposeChars");
if (pos.ch < cm.getLine(pos.line).length) pos = Pos(pos.line, pos.ch + 1);
var from = cm.findPosH(pos, -2, "char");
var range = cm.getRange(from, pos);
if (range.length != 2) return;
cm.setSelection(from, pos);
cm.replaceSelection(range.charAt(1) + range.charAt(0), "end");
}), }),
"Alt-C": repeated(function(cm) { "Alt-C": repeated(function(cm) {
@@ -347,45 +371,39 @@
"Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd", "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
"Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace", "Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
"Alt-/": "autocomplete", "Alt-/": "autocomplete",
"Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto", "Enter": "newlineAndIndent",
"Ctrl-J": repeated(function(cm) { cm.replaceSelection("\n", "end"); }),
"Tab": "indentAuto",
"Alt-G": function(cm) {cm.setOption("keyMap", "emacs-Alt-G");}, "Alt-G G": function(cm) {
"Ctrl-X": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-X");},
"Ctrl-Q": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-Q");},
"Ctrl-U": addPrefixMap
};
CodeMirror.keyMap["emacs-Ctrl-X"] = {
"Tab": function(cm) {
cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit"));
},
"Ctrl-X": function(cm) {
cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor"));
},
"Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": repeated("undo"), "K": "close",
"Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
auto: "emacs", nofallthrough: true, disableInput: true
};
CodeMirror.keyMap["emacs-Alt-G"] = {
"G": function(cm) {
var prefix = getPrefix(cm, true); var prefix = getPrefix(cm, true);
if (prefix != null && prefix > 0) return cm.setCursor(prefix - 1); if (prefix != null && prefix > 0) return cm.setCursor(prefix - 1);
getInput(cm, "Goto line", function(str) { getInput(cm, "Goto line", function(str) {
var num; var num;
if (str && !isNaN(num = Number(str)) && num == num|0 && num > 0) if (str && !isNaN(num = Number(str)) && num == (num|0) && num > 0)
cm.setCursor(num - 1); cm.setCursor(num - 1);
}); });
}, },
auto: "emacs", nofallthrough: true, disableInput: true
};
CodeMirror.keyMap["emacs-Ctrl-Q"] = { "Ctrl-X Tab": function(cm) {
"Tab": repeated("insertTab"), cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit"));
auto: "emacs", nofallthrough: true },
}; "Ctrl-X Ctrl-X": function(cm) {
cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor"));
},
"Ctrl-X Ctrl-S": "save",
"Ctrl-X Ctrl-W": "save",
"Ctrl-X S": "saveAll",
"Ctrl-X F": "open",
"Ctrl-X U": repeated("undo"),
"Ctrl-X K": "close",
"Ctrl-X Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
"Ctrl-X H": "selectAll",
"Ctrl-Q Tab": repeated("insertTab"),
"Ctrl-U": addPrefixMap
});
var prefixMap = {"Ctrl-G": clearPrefix}; var prefixMap = {"Ctrl-G": clearPrefix};
function regPrefix(d) { function regPrefix(d) {
@@ -395,4 +413,4 @@
} }
for (var i = 0; i < 10; ++i) regPrefix(String(i)); for (var i = 0; i < 10; ++i) regPrefix(String(i));
regPrefix("-"); regPrefix("-");
})(); });

View File

@@ -1,43 +0,0 @@
// A number of additional default bindings that are too obscure to
// include in the core codemirror.js file.
(function() {
"use strict";
var Pos = CodeMirror.Pos;
function moveLines(cm, start, end, dist) {
if (!dist || start > end) return 0;
var from = cm.clipPos(Pos(start, 0)), to = cm.clipPos(Pos(end));
var text = cm.getRange(from, to);
if (start <= cm.firstLine())
cm.replaceRange("", from, Pos(to.line + 1, 0));
else
cm.replaceRange("", Pos(from.line - 1), to);
var target = from.line + dist;
if (target <= cm.firstLine()) {
cm.replaceRange(text + "\n", Pos(target, 0));
return cm.firstLine() - from.line;
} else {
var targetPos = cm.clipPos(Pos(target - 1));
cm.replaceRange("\n" + text, targetPos);
return targetPos.line + 1 - from.line;
}
}
function moveSelectedLines(cm, dist) {
var head = cm.getCursor("head"), anchor = cm.getCursor("anchor");
cm.operation(function() {
var moved = moveLines(cm, Math.min(head.line, anchor.line), Math.max(head.line, anchor.line), dist);
cm.setSelection(Pos(anchor.line + moved, anchor.ch), Pos(head.line + moved, head.ch));
});
}
CodeMirror.commands.moveLinesUp = function(cm) { moveSelectedLines(cm, -1); };
CodeMirror.commands.moveLinesDown = function(cm) { moveSelectedLines(cm, 1); };
CodeMirror.keyMap["default"]["Alt-Up"] = "moveLinesUp";
CodeMirror.keyMap["default"]["Alt-Down"] = "moveLinesDown";
})();

596
gulliver/js/codemirror/keymap/sublime.js vendored Normal file
View File

@@ -0,0 +1,596 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// A rough approximation of Sublime Text's keybindings
// Depends on addon/search/searchcursor.js and optionally addon/dialog/dialogs.js
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../lib/codemirror"), require("../addon/search/searchcursor"), require("../addon/edit/matchbrackets"));
else if (typeof define == "function" && define.amd) // AMD
define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/edit/matchbrackets"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var map = CodeMirror.keyMap.sublime = {fallthrough: "default"};
var cmds = CodeMirror.commands;
var Pos = CodeMirror.Pos;
var mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault;
var ctrl = mac ? "Cmd-" : "Ctrl-";
// This is not exactly Sublime's algorithm. I couldn't make heads or tails of that.
function findPosSubword(doc, start, dir) {
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 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 if (state == "in") {
if (type != cat) {
if (type == "w" && cat == "W" && dir < 0) pos--;
if (type == "W" && cat == "w" && dir > 0) { type = "w"; continue; }
break;
}
}
}
return Pos(start.line, pos);
}
function moveSubword(cm, dir) {
cm.extendSelectionsBy(function(range) {
if (cm.display.shift || cm.doc.extend || range.empty())
return findPosSubword(cm.doc, range.head, dir);
else
return dir < 0 ? range.from() : range.to();
});
}
var goSubwordCombo = mac ? "Ctrl-" : "Alt-";
cmds[map[goSubwordCombo + "Left"] = "goSubwordLeft"] = function(cm) { moveSubword(cm, -1); };
cmds[map[goSubwordCombo + "Right"] = "goSubwordRight"] = function(cm) { moveSubword(cm, 1); };
if (mac) map["Cmd-Left"] = "goLineStartSmart";
var scrollLineCombo = mac ? "Ctrl-Alt-" : "Ctrl-";
cmds[map[scrollLineCombo + "Up"] = "scrollLineUp"] = function(cm) {
var info = cm.getScrollInfo();
if (!cm.somethingSelected()) {
var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local");
if (cm.getCursor().line >= visibleBottomLine)
cm.execCommand("goLineUp");
}
cm.scrollTo(null, info.top - cm.defaultTextHeight());
};
cmds[map[scrollLineCombo + "Down"] = "scrollLineDown"] = function(cm) {
var info = cm.getScrollInfo();
if (!cm.somethingSelected()) {
var visibleTopLine = cm.lineAtHeight(info.top, "local")+1;
if (cm.getCursor().line <= visibleTopLine)
cm.execCommand("goLineDown");
}
cm.scrollTo(null, info.top + cm.defaultTextHeight());
};
cmds[map["Shift-" + ctrl + "L"] = "splitSelectionByLine"] = function(cm) {
var ranges = cm.listSelections(), lineRanges = [];
for (var i = 0; i < ranges.length; i++) {
var from = ranges[i].from(), to = ranges[i].to();
for (var line = from.line; line <= to.line; ++line)
if (!(to.line > from.line && line == to.line && to.ch == 0))
lineRanges.push({anchor: line == from.line ? from : Pos(line, 0),
head: line == to.line ? to : Pos(line)});
}
cm.setSelections(lineRanges, 0);
};
map["Shift-Tab"] = "indentLess";
cmds[map["Esc"] = "singleSelectionTop"] = function(cm) {
var range = cm.listSelections()[0];
cm.setSelection(range.anchor, range.head, {scroll: false});
};
cmds[map[ctrl + "L"] = "selectLine"] = function(cm) {
var ranges = cm.listSelections(), extended = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
extended.push({anchor: Pos(range.from().line, 0),
head: Pos(range.to().line + 1, 0)});
}
cm.setSelections(extended);
};
map["Shift-Ctrl-K"] = "deleteLine";
function insertLine(cm, above) {
if (cm.isReadOnly()) return CodeMirror.Pass
cm.operation(function() {
var len = cm.listSelections().length, newSelection = [], last = -1;
for (var i = 0; i < len; i++) {
var head = cm.listSelections()[i].head;
if (head.line <= last) continue;
var at = Pos(head.line + (above ? 0 : 1), 0);
cm.replaceRange("\n", at, null, "+insertLine");
cm.indentLine(at.line, null, true);
newSelection.push({head: at, anchor: at});
last = head.line + 1;
}
cm.setSelections(newSelection);
});
cm.execCommand("indentAuto");
}
cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { return insertLine(cm, false); };
cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { return insertLine(cm, true); };
function wordAt(cm, pos) {
var start = pos.ch, end = start, line = cm.getLine(pos.line);
while (start && CodeMirror.isWordChar(line.charAt(start - 1))) --start;
while (end < line.length && CodeMirror.isWordChar(line.charAt(end))) ++end;
return {from: Pos(pos.line, start), to: Pos(pos.line, end), word: line.slice(start, end)};
}
cmds[map[ctrl + "D"] = "selectNextOccurrence"] = function(cm) {
var from = cm.getCursor("from"), to = cm.getCursor("to");
var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel;
if (CodeMirror.cmpPos(from, to) == 0) {
var word = wordAt(cm, from);
if (!word.word) return;
cm.setSelection(word.from, word.to);
fullWord = true;
} else {
var text = cm.getRange(from, to);
var query = fullWord ? new RegExp("\\b" + text + "\\b") : text;
var cur = cm.getSearchCursor(query, to);
var found = cur.findNext();
if (!found) {
cur = cm.getSearchCursor(query, Pos(cm.firstLine(), 0));
found = cur.findNext();
}
if (!found || isSelectedRange(cm.listSelections(), cur.from(), cur.to()))
return CodeMirror.Pass
cm.addSelection(cur.from(), cur.to());
}
if (fullWord)
cm.state.sublimeFindFullWord = cm.doc.sel;
};
function isSelectedRange(ranges, from, to) {
for (var i = 0; i < ranges.length; i++)
if (ranges[i].from() == from && ranges[i].to() == to) return true
return false
}
var mirror = "(){}[]";
function selectBetweenBrackets(cm) {
var ranges = cm.listSelections(), newRanges = []
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], pos = range.head, opening = cm.scanForBracket(pos, -1);
if (!opening) return false;
for (;;) {
var closing = cm.scanForBracket(pos, 1);
if (!closing) return false;
if (closing.ch == mirror.charAt(mirror.indexOf(opening.ch) + 1)) {
newRanges.push({anchor: Pos(opening.pos.line, opening.pos.ch + 1),
head: closing.pos});
break;
}
pos = Pos(closing.pos.line, closing.pos.ch + 1);
}
}
cm.setSelections(newRanges);
return true;
}
cmds[map["Shift-" + ctrl + "Space"] = "selectScope"] = function(cm) {
selectBetweenBrackets(cm) || cm.execCommand("selectAll");
};
cmds[map["Shift-" + ctrl + "M"] = "selectBetweenBrackets"] = function(cm) {
if (!selectBetweenBrackets(cm)) return CodeMirror.Pass;
};
cmds[map[ctrl + "M"] = "goToBracket"] = function(cm) {
cm.extendSelectionsBy(function(range) {
var next = cm.scanForBracket(range.head, 1);
if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos;
var prev = cm.scanForBracket(range.head, -1);
return prev && Pos(prev.pos.line, prev.pos.ch + 1) || range.head;
});
};
var swapLineCombo = mac ? "Cmd-Ctrl-" : "Shift-Ctrl-";
cmds[map[swapLineCombo + "Up"] = "swapLineUp"] = function(cm) {
if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], from = range.from().line - 1, to = range.to().line;
newSels.push({anchor: Pos(range.anchor.line - 1, range.anchor.ch),
head: Pos(range.head.line - 1, range.head.ch)});
if (range.to().ch == 0 && !range.empty()) --to;
if (from > at) linesToMove.push(from, to);
else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to;
at = to;
}
cm.operation(function() {
for (var i = 0; i < linesToMove.length; i += 2) {
var from = linesToMove[i], to = linesToMove[i + 1];
var line = cm.getLine(from);
cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine");
if (to > cm.lastLine())
cm.replaceRange("\n" + line, Pos(cm.lastLine()), null, "+swapLine");
else
cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine");
}
cm.setSelections(newSels);
cm.scrollIntoView();
});
};
cmds[map[swapLineCombo + "Down"] = "swapLineDown"] = function(cm) {
if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1;
for (var i = ranges.length - 1; i >= 0; i--) {
var range = ranges[i], from = range.to().line + 1, to = range.from().line;
if (range.to().ch == 0 && !range.empty()) from--;
if (from < at) linesToMove.push(from, to);
else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to;
at = to;
}
cm.operation(function() {
for (var i = linesToMove.length - 2; i >= 0; i -= 2) {
var from = linesToMove[i], to = linesToMove[i + 1];
var line = cm.getLine(from);
if (from == cm.lastLine())
cm.replaceRange("", Pos(from - 1), Pos(from), "+swapLine");
else
cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine");
cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine");
}
cm.scrollIntoView();
});
};
cmds[map[ctrl + "/"] = "toggleCommentIndented"] = function(cm) {
cm.toggleComment({ indent: true });
}
cmds[map[ctrl + "J"] = "joinLines"] = function(cm) {
var ranges = cm.listSelections(), joined = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], from = range.from();
var start = from.line, end = range.to().line;
while (i < ranges.length - 1 && ranges[i + 1].from().line == end)
end = ranges[++i].to().line;
joined.push({start: start, end: end, anchor: !range.empty() && from});
}
cm.operation(function() {
var offset = 0, ranges = [];
for (var i = 0; i < joined.length; i++) {
var obj = joined[i];
var anchor = obj.anchor && Pos(obj.anchor.line - offset, obj.anchor.ch), head;
for (var line = obj.start; line <= obj.end; line++) {
var actual = line - offset;
if (line == obj.end) head = Pos(actual, cm.getLine(actual).length + 1);
if (actual < cm.lastLine()) {
cm.replaceRange(" ", Pos(actual), Pos(actual + 1, /^\s*/.exec(cm.getLine(actual + 1))[0].length));
++offset;
}
}
ranges.push({anchor: anchor || head, head: head});
}
cm.setSelections(ranges, 0);
});
};
cmds[map["Shift-" + ctrl + "D"] = "duplicateLine"] = function(cm) {
cm.operation(function() {
var rangeCount = cm.listSelections().length;
for (var i = 0; i < rangeCount; i++) {
var range = cm.listSelections()[i];
if (range.empty())
cm.replaceRange(cm.getLine(range.head.line) + "\n", Pos(range.head.line, 0));
else
cm.replaceRange(cm.getRange(range.from(), range.to()), range.from());
}
cm.scrollIntoView();
});
};
if (!mac) map[ctrl + "T"] = "transposeChars";
function sortLines(cm, caseSensitive) {
if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), toSort = [], selected;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (range.empty()) continue;
var from = range.from().line, to = range.to().line;
while (i < ranges.length - 1 && ranges[i + 1].from().line == to)
to = ranges[++i].to().line;
if (!ranges[i].to().ch) to--;
toSort.push(from, to);
}
if (toSort.length) selected = true;
else toSort.push(cm.firstLine(), cm.lastLine());
cm.operation(function() {
var ranges = [];
for (var i = 0; i < toSort.length; i += 2) {
var from = toSort[i], to = toSort[i + 1];
var start = Pos(from, 0), end = Pos(to);
var lines = cm.getRange(start, end, false);
if (caseSensitive)
lines.sort();
else
lines.sort(function(a, b) {
var au = a.toUpperCase(), bu = b.toUpperCase();
if (au != bu) { a = au; b = bu; }
return a < b ? -1 : a == b ? 0 : 1;
});
cm.replaceRange(lines, start, end);
if (selected) ranges.push({anchor: start, head: Pos(to + 1, 0)});
}
if (selected) cm.setSelections(ranges, 0);
});
}
cmds[map["F9"] = "sortLines"] = function(cm) { sortLines(cm, true); };
cmds[map[ctrl + "F9"] = "sortLinesInsensitive"] = function(cm) { sortLines(cm, false); };
cmds[map["F2"] = "nextBookmark"] = function(cm) {
var marks = cm.state.sublimeBookmarks;
if (marks) while (marks.length) {
var current = marks.shift();
var found = current.find();
if (found) {
marks.push(current);
return cm.setSelection(found.from, found.to);
}
}
};
cmds[map["Shift-F2"] = "prevBookmark"] = function(cm) {
var marks = cm.state.sublimeBookmarks;
if (marks) while (marks.length) {
marks.unshift(marks.pop());
var found = marks[marks.length - 1].find();
if (!found)
marks.pop();
else
return cm.setSelection(found.from, found.to);
}
};
cmds[map[ctrl + "F2"] = "toggleBookmark"] = function(cm) {
var ranges = cm.listSelections();
var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []);
for (var i = 0; i < ranges.length; i++) {
var from = ranges[i].from(), to = ranges[i].to();
var found = cm.findMarks(from, to);
for (var j = 0; j < found.length; j++) {
if (found[j].sublimeBookmark) {
found[j].clear();
for (var k = 0; k < marks.length; k++)
if (marks[k] == found[j])
marks.splice(k--, 1);
break;
}
}
if (j == found.length)
marks.push(cm.markText(from, to, {sublimeBookmark: true, clearWhenEmpty: false}));
}
};
cmds[map["Shift-" + ctrl + "F2"] = "clearBookmarks"] = function(cm) {
var marks = cm.state.sublimeBookmarks;
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear();
marks.length = 0;
};
cmds[map["Alt-F2"] = "selectBookmarks"] = function(cm) {
var marks = cm.state.sublimeBookmarks, ranges = [];
if (marks) for (var i = 0; i < marks.length; i++) {
var found = marks[i].find();
if (!found)
marks.splice(i--, 0);
else
ranges.push({anchor: found.from, head: found.to});
}
if (ranges.length)
cm.setSelections(ranges, 0);
};
map["Alt-Q"] = "wrapLines";
var cK = ctrl + "K ";
function modifyWordOrSelection(cm, mod) {
cm.operation(function() {
var ranges = cm.listSelections(), indices = [], replacements = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (range.empty()) { indices.push(i); replacements.push(""); }
else replacements.push(mod(cm.getRange(range.from(), range.to())));
}
cm.replaceSelections(replacements, "around", "case");
for (var i = indices.length - 1, at; i >= 0; i--) {
var range = ranges[indices[i]];
if (at && CodeMirror.cmpPos(range.head, at) > 0) continue;
var word = wordAt(cm, range.head);
at = word.from;
cm.replaceRange(mod(word.word), word.from, word.to);
}
});
}
map[cK + ctrl + "Backspace"] = "delLineLeft";
cmds[map["Backspace"] = "smartBackspace"] = function(cm) {
if (cm.somethingSelected()) return CodeMirror.Pass;
cm.operation(function() {
var cursors = cm.listSelections();
var indentUnit = cm.getOption("indentUnit");
for (var i = cursors.length - 1; i >= 0; i--) {
var cursor = cursors[i].head;
var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor);
var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize"));
// Delete by one character by default
var deletePos = cm.findPosH(cursor, -1, "char", false);
if (toStartOfLine && !/\S/.test(toStartOfLine) && column % indentUnit == 0) {
var prevIndent = new Pos(cursor.line,
CodeMirror.findColumn(toStartOfLine, column - indentUnit, indentUnit));
// Smart delete only if we found a valid prevIndent location
if (prevIndent.ch != cursor.ch) deletePos = prevIndent;
}
cm.replaceRange("", deletePos, cursor, "+delete");
}
});
};
cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = ranges.length - 1; i >= 0; i--)
cm.replaceRange("", ranges[i].anchor, Pos(ranges[i].to().line), "+delete");
cm.scrollIntoView();
});
};
cmds[map[cK + ctrl + "U"] = "upcaseAtCursor"] = function(cm) {
modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); });
};
cmds[map[cK + ctrl + "L"] = "downcaseAtCursor"] = function(cm) {
modifyWordOrSelection(cm, function(str) { return str.toLowerCase(); });
};
cmds[map[cK + ctrl + "Space"] = "setSublimeMark"] = function(cm) {
if (cm.state.sublimeMark) cm.state.sublimeMark.clear();
cm.state.sublimeMark = cm.setBookmark(cm.getCursor());
};
cmds[map[cK + ctrl + "A"] = "selectToSublimeMark"] = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) cm.setSelection(cm.getCursor(), found);
};
cmds[map[cK + ctrl + "W"] = "deleteToSublimeMark"] = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) {
var from = cm.getCursor(), to = found;
if (CodeMirror.cmpPos(from, to) > 0) { var tmp = to; to = from; from = tmp; }
cm.state.sublimeKilled = cm.getRange(from, to);
cm.replaceRange("", from, to);
}
};
cmds[map[cK + ctrl + "X"] = "swapWithSublimeMark"] = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) {
cm.state.sublimeMark.clear();
cm.state.sublimeMark = cm.setBookmark(cm.getCursor());
cm.setCursor(found);
}
};
cmds[map[cK + ctrl + "Y"] = "sublimeYank"] = function(cm) {
if (cm.state.sublimeKilled != null)
cm.replaceSelection(cm.state.sublimeKilled, null, "paste");
};
map[cK + ctrl + "G"] = "clearBookmarks";
cmds[map[cK + ctrl + "C"] = "showInCenter"] = function(cm) {
var pos = cm.cursorCoords(null, "local");
cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2);
};
var selectLinesCombo = mac ? "Ctrl-Shift-" : "Ctrl-Alt-";
cmds[map[selectLinesCombo + "Up"] = "selectLinesUpward"] = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (range.head.line > cm.firstLine())
cm.addSelection(Pos(range.head.line - 1, range.head.ch));
}
});
};
cmds[map[selectLinesCombo + "Down"] = "selectLinesDownward"] = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (range.head.line < cm.lastLine())
cm.addSelection(Pos(range.head.line + 1, range.head.ch));
}
});
};
function getTarget(cm) {
var from = cm.getCursor("from"), to = cm.getCursor("to");
if (CodeMirror.cmpPos(from, to) == 0) {
var word = wordAt(cm, from);
if (!word.word) return;
from = word.from;
to = word.to;
}
return {from: from, to: to, query: cm.getRange(from, to), word: word};
}
function findAndGoTo(cm, forward) {
var target = getTarget(cm);
if (!target) return;
var query = target.query;
var cur = cm.getSearchCursor(query, forward ? target.to : target.from);
if (forward ? cur.findNext() : cur.findPrevious()) {
cm.setSelection(cur.from(), cur.to());
} else {
cur = cm.getSearchCursor(query, forward ? Pos(cm.firstLine(), 0)
: cm.clipPos(Pos(cm.lastLine())));
if (forward ? cur.findNext() : cur.findPrevious())
cm.setSelection(cur.from(), cur.to());
else if (target.word)
cm.setSelection(target.from, target.to);
}
};
cmds[map[ctrl + "F3"] = "findUnder"] = function(cm) { findAndGoTo(cm, true); };
cmds[map["Shift-" + ctrl + "F3"] = "findUnderPrevious"] = function(cm) { findAndGoTo(cm,false); };
cmds[map["Alt-F3"] = "findAllUnder"] = function(cm) {
var target = getTarget(cm);
if (!target) return;
var cur = cm.getSearchCursor(target.query);
var matches = [];
var primaryIndex = -1;
while (cur.findNext()) {
matches.push({anchor: cur.from(), head: cur.to()});
if (cur.from().line <= target.from.line && cur.from().ch <= target.from.ch)
primaryIndex++;
}
cm.setSelections(matches, primaryIndex);
};
map["Shift-" + ctrl + "["] = "fold";
map["Shift-" + ctrl + "]"] = "unfold";
map[cK + ctrl + "0"] = map[cK + ctrl + "J"] = "unfoldAll";
map[ctrl + "I"] = "findIncremental";
map["Shift-" + ctrl + "I"] = "findIncrementalReverse";
map[ctrl + "H"] = "replace";
map["F3"] = "findNext";
map["Shift-F3"] = "findPrev";
CodeMirror.normalizeKeyMap(map);
});

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,7 @@
/* Set height, width, borders, and global font properties here */ /* Set height, width, borders, and global font properties here */
font-family: monospace; font-family: monospace;
height: 300px; height: 300px;
} color: black;
.CodeMirror-scroll {
/* Set scrolling behaviour here */
overflow: auto;
} }
/* PADDING */ /* PADDING */
@@ -36,40 +33,93 @@
min-width: 20px; min-width: 20px;
text-align: right; text-align: right;
color: #999; color: #999;
white-space: nowrap;
} }
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */ /* CURSOR */
.CodeMirror div.CodeMirror-cursor { .CodeMirror-cursor {
border-left: 1px solid black; border-left: 1px solid black;
z-index: 3; border-right: none;
width: 0;
} }
/* Shown when moving in bi-directional text */ /* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor { .CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver; border-left: 1px solid silver;
} }
.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { .cm-fat-cursor .CodeMirror-cursor {
width: auto; width: auto;
border: 0; border: 0 !important;
background: #7e7; background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1; z-index: 1;
} }
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
.cm-tab { display: inline-block; } .cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: -20px;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
/* DEFAULT THEME */ /* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;} .cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;} .cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;} .cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;} .cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable {color: black;} .cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;} .cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3 {color: #085;} .cm-s-default .cm-variable-3 {color: #085;}
.cm-s-default .cm-property {color: black;}
.cm-s-default .cm-operator {color: black;}
.cm-s-default .cm-comment {color: #a50;} .cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;} .cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;} .cm-s-default .cm-string-2 {color: #f50;}
@@ -79,22 +129,19 @@
.cm-s-default .cm-bracket {color: #997;} .cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;} .cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;} .cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-s-default .cm-hr {color: #999;} .cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;} .cm-s-default .cm-link {color: #00c;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-s-default .cm-error {color: #f00;} .cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;} .cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;} .CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */ /* STOP */
@@ -103,30 +150,28 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
the editor. You probably shouldn't touch them. */ the editor. You probably shouldn't touch them. */
.CodeMirror { .CodeMirror {
line-height: 1;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
background: white; background: white;
color: black;
} }
.CodeMirror-scroll { .CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */ /* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */ /* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px; margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px; padding-right: 30px; padding-bottom: 30px;
height: 100%; height: 100%;
outline: none; /* Prevent dragging from highlighting the element */ outline: none; /* Prevent dragging from highlighting the element */
position: relative; position: relative;
-moz-box-sizing: content-box;
box-sizing: content-box;
} }
.CodeMirror-sizer { .CodeMirror-sizer {
position: relative; position: relative;
border-right: 30px solid transparent;
} }
/* The fake, visible scrollbars. Used to force redraw during scrolling /* The fake, visible scrollbars. Used to force redraw during scrolling
before actuall scrolling happens, thus preventing shaking and before actual scrolling happens, thus preventing shaking and
flickering artifacts. */ flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute; position: absolute;
@@ -152,29 +197,38 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-gutters { .CodeMirror-gutters {
position: absolute; left: 0; top: 0; position: absolute; left: 0; top: 0;
padding-bottom: 30px; min-height: 100%;
z-index: 3; z-index: 3;
} }
.CodeMirror-gutter { .CodeMirror-gutter {
white-space: normal; white-space: normal;
height: 100%; height: 100%;
-moz-box-sizing: content-box;
box-sizing: content-box;
padding-bottom: 30px;
margin-bottom: -32px;
display: inline-block; display: inline-block;
/* Hack to make IE7 behave */ vertical-align: top;
*zoom:1; margin-bottom: -30px;
*display:inline; }
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
} }
.CodeMirror-gutter-elt { .CodeMirror-gutter-elt {
position: absolute; position: absolute;
cursor: default; cursor: default;
z-index: 4; z-index: 4;
} }
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-lines { .CodeMirror-lines {
cursor: text; cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
} }
.CodeMirror pre { .CodeMirror pre {
/* Reset some styles that the rest of the page might have set */ /* Reset some styles that the rest of the page might have set */
@@ -191,22 +245,16 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
z-index: 2; z-index: 2;
position: relative; position: relative;
overflow: visible; overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
} }
.CodeMirror-wrap pre { .CodeMirror-wrap pre {
word-wrap: break-word; word-wrap: break-word;
white-space: pre-wrap; white-space: pre-wrap;
word-break: normal; word-break: normal;
} }
.CodeMirror-code pre {
border-right: 30px solid transparent;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
}
.CodeMirror-wrap .CodeMirror-code pre {
border-right: none;
width: auto;
}
.CodeMirror-linebackground { .CodeMirror-linebackground {
position: absolute; position: absolute;
left: 0; right: 0; top: 0; bottom: 0; left: 0; right: 0; top: 0; bottom: 0;
@@ -221,8 +269,20 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-widget {} .CodeMirror-widget {}
.CodeMirror-wrap .CodeMirror-scroll { .CodeMirror-rtl pre { direction: rtl; }
overflow-x: hidden;
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
} }
.CodeMirror-measure { .CodeMirror-measure {
@@ -232,32 +292,49 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
overflow: hidden; overflow: hidden;
visibility: hidden; visibility: hidden;
} }
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; } .CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { div.CodeMirror-cursors {
position: absolute;
visibility: hidden; visibility: hidden;
border-right: none; position: relative;
width: 0; z-index: 3;
} }
.CodeMirror-focused div.CodeMirror-cursor { div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible; visibility: visible;
} }
.CodeMirror-selected { background: #d9d9d9; } .CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching { .cm-searching {
background: #ffa; background: #ffa;
background: rgba(255, 255, 0, .4); background: rgba(255, 255, 0, .4);
} }
/* IE7 hack to prevent it from returning funny offsetTops on the spans */ /* Used to force a border model for a node */
.CodeMirror span { *vertical-align: text-bottom; } .cm-force-border { padding-right: .1px; }
@media print { @media print {
/* Hide the cursor when printing */ /* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursor { .CodeMirror div.CodeMirror-cursors {
visibility: hidden; visibility: hidden;
} }
} }
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,16 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.defineMode("apl", function() { CodeMirror.defineMode("apl", function() {
var builtInOps = { var builtInOps = {
".": "innerProduct", ".": "innerProduct",
@@ -89,7 +102,7 @@ CodeMirror.defineMode("apl", function() {
}; };
}, },
token: function(stream, state) { token: function(stream, state) {
var ch, funcName, word; var ch, funcName;
if (stream.eatSpace()) { if (stream.eatSpace()) {
return null; return null;
} }
@@ -150,7 +163,6 @@ CodeMirror.defineMode("apl", function() {
return "function jot-dot"; return "function jot-dot";
} }
stream.eatWhile(/[\w\$_]/); stream.eatWhile(/[\w\$_]/);
word = stream.current();
state.prev = true; state.prev = true;
return "keyword"; return "keyword";
} }
@@ -158,3 +170,5 @@ CodeMirror.defineMode("apl", function() {
}); });
CodeMirror.defineMIME("text/apl", "apl"); CodeMirror.defineMIME("text/apl", "apl");
});

View File

@@ -12,12 +12,12 @@
.CodeMirror { border: 2px inset #dee; } .CodeMirror { border: 2px inset #dee; }
</style> </style>
<div id=nav> <div id=nav>
<a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a> <a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul> <ul>
<li><a href="../../index.html">Home</a> <li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a> <li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a> <li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul> </ul>
<ul> <ul>
<li><a href="../index.html">Language modes</a> <li><a href="../index.html">Language modes</a>

View File

@@ -0,0 +1,73 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
function errorIfNotEmpty(stream) {
var nonWS = stream.match(/^\s*\S/);
stream.skipToEnd();
return nonWS ? "error" : null;
}
CodeMirror.defineMode("asciiarmor", function() {
return {
token: function(stream, state) {
var m;
if (state.state == "top") {
if (stream.sol() && (m = stream.match(/^-----BEGIN (.*)?-----\s*$/))) {
state.state = "headers";
state.type = m[1];
return "tag";
}
return errorIfNotEmpty(stream);
} else if (state.state == "headers") {
if (stream.sol() && stream.match(/^\w+:/)) {
state.state = "header";
return "atom";
} else {
var result = errorIfNotEmpty(stream);
if (result) state.state = "body";
return result;
}
} else if (state.state == "header") {
stream.skipToEnd();
state.state = "headers";
return "string";
} else if (state.state == "body") {
if (stream.sol() && (m = stream.match(/^-----END (.*)?-----\s*$/))) {
if (m[1] != state.type) return "error";
state.state = "end";
return "tag";
} else {
if (stream.eatWhile(/[A-Za-z0-9+\/=]/)) {
return null;
} else {
stream.next();
return "error";
}
}
} else if (state.state == "end") {
return errorIfNotEmpty(stream);
}
},
blankLine: function(state) {
if (state.state == "headers") state.state = "body";
},
startState: function() {
return {state: "top", type: null};
}
};
});
CodeMirror.defineMIME("application/pgp", "asciiarmor");
CodeMirror.defineMIME("application/pgp-keys", "asciiarmor");
CodeMirror.defineMIME("application/pgp-signature", "asciiarmor");
});

View File

@@ -0,0 +1,46 @@
<!doctype html>
<title>CodeMirror: ASCII Armor (PGP) mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="asciiarmor.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">ASCII Armor</a>
</ul>
</div>
<article>
<h2>ASCII Armor (PGP) mode</h2>
<form><textarea id="code" name="code">
-----BEGIN PGP MESSAGE-----
Version: OpenPrivacy 0.99
yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS
vBSFjNSiVHsuAA==
=njUN
-----END PGP MESSAGE-----
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true
});
</script>
<p><strong>MIME types
defined:</strong> <code>application/pgp</code>, <code>application/pgp-keys</code>, <code>application/pgp-signature</code></p>
</article>

View File

@@ -0,0 +1,204 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://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) {
"use strict";
CodeMirror.defineMode("asn.1", function(config, parserConfig) {
var indentUnit = config.indentUnit,
keywords = parserConfig.keywords || {},
cmipVerbs = parserConfig.cmipVerbs || {},
compareTypes = parserConfig.compareTypes || {},
status = parserConfig.status || {},
tags = parserConfig.tags || {},
storage = parserConfig.storage || {},
modifier = parserConfig.modifier || {},
accessTypes = parserConfig.accessTypes|| {},
multiLineStrings = parserConfig.multiLineStrings,
indentStatements = parserConfig.indentStatements !== false;
var isOperatorChar = /[\|\^]/;
var curPunc;
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\[\]\(\){}:=,;]/.test(ch)) {
curPunc = ch;
return "punctuation";
}
if (ch == "-"){
if (stream.eat("-")) {
stream.skipToEnd();
return "comment";
}
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
return "number";
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\-]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) return "keyword";
if (cmipVerbs.propertyIsEnumerable(cur)) return "variable cmipVerbs";
if (compareTypes.propertyIsEnumerable(cur)) return "atom compareTypes";
if (status.propertyIsEnumerable(cur)) return "comment status";
if (tags.propertyIsEnumerable(cur)) return "variable-3 tags";
if (storage.propertyIsEnumerable(cur)) return "builtin storage";
if (modifier.propertyIsEnumerable(cur)) return "string-2 modifier";
if (accessTypes.propertyIsEnumerable(cur)) return "atom accessTypes";
return "variable";
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped){
var afterNext = stream.peek();
//look if the character if the quote is like the B in '10100010'B
if (afterNext){
afterNext = afterNext.toLowerCase();
if(afterNext == "b" || afterNext == "h" || afterNext == "o")
stream.next();
}
end = true; break;
}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
state.tokenize = null;
return "string";
};
}
function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
var indent = state.indented;
if (state.context && state.context.type == "statement")
indent = state.context.indented;
return state.context = new Context(indent, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}
//Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},
token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment") return style;
if (ctx.align == null) ctx.align = true;
if ((curPunc == ";" || curPunc == ":" || curPunc == ",")
&& ctx.type == "statement"){
popContext(state);
}
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (indentStatements && (((ctx.type == "}" || ctx.type == "top")
&& curPunc != ';') || (ctx.type == "statement"
&& curPunc == "newstatement")))
pushContext(state, stream.column(), "statement");
state.startOfLine = false;
return style;
},
electricChars: "{}",
lineComment: "--",
fold: "brace"
};
});
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
CodeMirror.defineMIME("text/x-ttcn-asn", {
name: "asn.1",
keywords: words("DEFINITIONS OBJECTS IF DERIVED INFORMATION ACTION" +
" REPLY ANY NAMED CHARACTERIZED BEHAVIOUR REGISTERED" +
" WITH AS IDENTIFIED CONSTRAINED BY PRESENT BEGIN" +
" IMPORTS FROM UNITS SYNTAX MIN-ACCESS MAX-ACCESS" +
" MINACCESS MAXACCESS REVISION STATUS DESCRIPTION" +
" SEQUENCE SET COMPONENTS OF CHOICE DistinguishedName" +
" ENUMERATED SIZE MODULE END INDEX AUGMENTS EXTENSIBILITY" +
" IMPLIED EXPORTS"),
cmipVerbs: words("ACTIONS ADD GET NOTIFICATIONS REPLACE REMOVE"),
compareTypes: words("OPTIONAL DEFAULT MANAGED MODULE-TYPE MODULE_IDENTITY" +
" MODULE-COMPLIANCE OBJECT-TYPE OBJECT-IDENTITY" +
" OBJECT-COMPLIANCE MODE CONFIRMED CONDITIONAL" +
" SUBORDINATE SUPERIOR CLASS TRUE FALSE NULL" +
" TEXTUAL-CONVENTION"),
status: words("current deprecated mandatory obsolete"),
tags: words("APPLICATION AUTOMATIC EXPLICIT IMPLICIT PRIVATE TAGS" +
" UNIVERSAL"),
storage: words("BOOLEAN INTEGER OBJECT IDENTIFIER BIT OCTET STRING" +
" UTCTime InterfaceIndex IANAifType CMIP-Attribute" +
" REAL PACKAGE PACKAGES IpAddress PhysAddress" +
" NetworkAddress BITS BMPString TimeStamp TimeTicks" +
" TruthValue RowStatus DisplayString GeneralString" +
" GraphicString IA5String NumericString" +
" PrintableString SnmpAdminAtring TeletexString" +
" UTF8String VideotexString VisibleString StringStore" +
" ISO646String T61String UniversalString Unsigned32" +
" Integer32 Gauge Gauge32 Counter Counter32 Counter64"),
modifier: words("ATTRIBUTE ATTRIBUTES MANDATORY-GROUP MANDATORY-GROUPS" +
" GROUP GROUPS ELEMENTS EQUALITY ORDERING SUBSTRINGS" +
" DEFINED"),
accessTypes: words("not-accessible accessible-for-notify read-only" +
" read-create read-write"),
multiLineStrings: true
});
});

View File

@@ -0,0 +1,77 @@
<!doctype html>
<title>CodeMirror: ASN.1 mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="asn.1.js"></script>
<style type="text/css">
.CodeMirror {
border-top: 1px solid black;
border-bottom: 1px solid black;
}
</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1>
<img id=logo src="../../doc/logo.png">
</a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One">ASN.1</a>
</ul>
</div>
<article>
<h2>ASN.1 example</h2>
<div>
<textarea id="ttcn-asn-code">
--
-- Sample ASN.1 Code
--
MyModule DEFINITIONS ::=
BEGIN
MyTypes ::= SEQUENCE {
myObjectId OBJECT IDENTIFIER,
mySeqOf SEQUENCE OF MyInt,
myBitString BIT STRING {
muxToken(0),
modemToken(1)
}
}
MyInt ::= INTEGER (0..65535)
END
</textarea>
</div>
<script>
var ttcnEditor = CodeMirror.fromTextArea(document.getElementById("ttcn-asn-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-ttcn-asn"
});
ttcnEditor.setSize(400, 400);
var mac = CodeMirror.keyMap.default == CodeMirror.keyMap.macDefault;
CodeMirror.keyMap.default[(mac ? "Cmd" : "Ctrl") + "-Space"] = "autocomplete";
</script>
<br/>
<p><strong>Language:</strong> Abstract Syntax Notation One
(<a href="http://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx">ASN.1</a>)
</p>
<p><strong>MIME types defined:</strong> <code>text/x-ttcn-asn</code></p>
<br/>
<p>The development of this mode has been sponsored by <a href="http://www.ericsson.com/">Ericsson
</a>.</p>
<p>Coded by Asmelash Tsegay Gebretsadkan </p>
</article>

View File

@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
/* /*
* ===================================================================================== * =====================================================================================
* *
@@ -14,6 +17,16 @@
* ===================================================================================== * =====================================================================================
*/ */
(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) {
"use strict";
CodeMirror.defineMode("asterisk", function() { CodeMirror.defineMode("asterisk", function() {
var atoms = ["exten", "same", "include","ignorepat","switch"], var atoms = ["exten", "same", "include","ignorepat","switch"],
dpcmd = ["#include","#exec"], dpcmd = ["#include","#exec"],
@@ -52,8 +65,7 @@ CodeMirror.defineMode("asterisk", function() {
function basicToken(stream,state){ function basicToken(stream,state){
var cur = ''; var cur = '';
var ch = ''; var ch = stream.next();
ch = stream.next();
// comment // comment
if(ch == ";") { if(ch == ";") {
stream.skipToEnd(); stream.skipToEnd();
@@ -123,7 +135,6 @@ CodeMirror.defineMode("asterisk", function() {
token: function(stream, state) { token: function(stream, state) {
var cur = ''; var cur = '';
var ch = '';
if(stream.eatSpace()) return null; if(stream.eatSpace()) return null;
// extension started // extension started
if(state.extenStart){ if(state.extenStart){
@@ -157,7 +168,7 @@ CodeMirror.defineMode("asterisk", function() {
} else if(state.extenPriority) { } else if(state.extenPriority) {
state.extenPriority = false; state.extenPriority = false;
state.extenApplication = true; state.extenApplication = true;
ch = stream.next(); // get comma stream.next(); // get comma
if(state.extenSame) return null; if(state.extenSame) return null;
stream.eatWhile(/[^,]/); stream.eatWhile(/[^,]/);
return "number"; return "number";
@@ -181,3 +192,5 @@ CodeMirror.defineMode("asterisk", function() {
}); });
CodeMirror.defineMIME("text/x-asterisk", "asterisk"); CodeMirror.defineMIME("text/x-asterisk", "asterisk");
});

View File

@@ -12,12 +12,12 @@
.cm-s-default span.cm-arrow { color: red; } .cm-s-default span.cm-arrow { color: red; }
</style> </style>
<div id=nav> <div id=nav>
<a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a> <a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul> <ul>
<li><a href="../../index.html">Home</a> <li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a> <li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a> <li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul> </ul>
<ul> <ul>
<li><a href="../index.html">Language modes</a> <li><a href="../index.html">Language modes</a>

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