Compare commits

..

137 Commits

Author SHA1 Message Date
mdipierro
63224e8ce6 2.7.3 2013-10-11 18:10:57 -05:00
mdipierro
ff7f9568db fixed validation of nagtive integers, thanks Stefan 2013-10-11 18:06:57 -05:00
mdipierro
3635dd8faf fixed problem with Virtual Fields and grid 2013-10-11 17:59:30 -05:00
mdipierro
d5fda056ff simplified logic for number validators 2013-10-11 17:07:17 -05:00
mdipierro
d8e8d1d597 fixed problem with IS_INT_IN_RANGE for large numbers 2013-10-11 16:59:05 -05:00
mdipierro
59290534bc fixed issue 1708:gae memcache_contrib does not set the time_expire, thanks Nicholas 2013-10-09 11:58:15 -05:00
mdipierro
8fb0b71be6 fixed compilerapp sorting issue, better 2013-10-09 11:31:33 -05:00
mdipierro
ddc0fc9949 fixed compilerapp sorting issue, possibly 2013-10-09 11:15:07 -05:00
mdipierro
5428fdbd04 reverted error commit 2013-10-09 09:07:00 -05:00
Massimo
98f2bfbfb6 Merge branch 'master' of github.com:web2py/web2py 2013-10-08 11:39:30 -05:00
Massimo
d780d26cc9 merge heads 2013-10-08 11:38:28 -05:00
mdipierro
a5711bd933 Merge pull request #244 from timrichardson/issue/1692
fix for Issue 1692 virtual fields in SQLFORM.grid
2013-10-08 09:35:51 -07:00
mdipierro
b96cde2f77 Merge pull request #243 from cccaballero/master
more spanish translations
2013-10-08 09:34:16 -07:00
Tim Richardson
a3f3ed1298 fix for Issue 1692 virtual fields in forms 2013-10-08 13:31:36 +11:00
mdipierro
5f34193ac7 fixed demo mode 2013-10-07 09:17:51 -05:00
cccaballero
6fe6852a0c more spanish translations
more spanish translations
2013-10-07 09:49:48 -04:00
mdipierro
961d143f7d 2.7.2 2013-10-07 08:40:39 -05:00
mdipierro
0e98544a79 Merge pull request #242 from rhr/master
fix for using the shell with IPython >= 1.0
2013-10-06 19:37:56 -07:00
mdipierro
86d8b8dece Merge pull request #241 from spametki/master
IMAP fixed patch for google code issue 1707
2013-10-06 19:37:11 -07:00
Rick Ree
46e2a663e9 fix for using the shell with IPython >= 1.0 2013-10-06 17:18:04 -05:00
spametki
e7fbd0095f IMAP google code issue 1707: fixed patch 2013-10-06 14:39:23 -03:00
mdipierro
add6fa526e fixed regex status in http.py 2013-10-06 11:52:23 -05:00
mdipierro
47e77e9a9c Merge pull request #239 from abastardi/patch-1
Fixed problem with Rows.render
2013-10-06 08:15:09 -07:00
mdipierro
81036ac997 Merge pull request #237 from alfonsodg/master
Added gitignore restrictions and changes for admin.py
2013-10-06 08:13:58 -07:00
mdipierro
77df883566 Merge pull request #236 from niphlod/enhancement/anyserver_options
fixed gevent workers
2013-10-06 08:11:03 -07:00
mdipierro
bfc7e3b4e9 Merge pull request #238 from houdinihound/patch-1
Support for HTTP Status Code: 429 - Too Many Requests
2013-10-06 08:09:52 -07:00
spametki
e05fe15470 IMAP .insert support for custom date (Google Code issue 1707) 2013-10-06 12:09:44 -03:00
mdipierro
2a062a2ff5 fixed setup scripts for apache to use processes, not threads, thanks Thomas 2013-10-06 10:08:40 -05:00
abastardi
44e7b70dbc Fixed problem with Rows.render 2013-10-06 09:04:47 -04:00
Jose C
88abefb896 Support for HTTP Status Code: 429 - Too Many Requests
Currently raising HTTP 429 results in HTTP 500 being sent.  This patch resolves that issue.
2013-10-05 15:42:48 +01:00
mdipierro
06ca5e6857 grid refcator patch for ajax, thanks Niphlod 2013-10-05 08:52:45 -05:00
Alfonso de la Guarda Reyes
c1f8d34892 Minor fixes for pep and styles widget.py 2013-10-05 08:08:37 -05:00
Alfonso de la Guarda Reyes
5679661914 Minor fixes for pep and style 2013-10-05 08:03:50 -05:00
Alfonso de la Guarda Reyes
cd957cf52b Fixes for some pep and code syntax 2013-10-05 07:59:04 -05:00
Alfonso de la Guarda Reyes
fff798c1cc Added restriction for .idea inside gitignore 2013-10-05 07:51:12 -05:00
niphlod
b464d3185e fixed gevent workers 2013-10-05 13:43:03 +02:00
mdipierro
cfb68ff90f fixed ldap_auth.py 2013-10-04 21:31:39 -05:00
mdipierro
8418fca2f6 R-2.7.1 2013-10-04 15:14:53 -05:00
mdipierro
68c0baeb22 R-2.7.1 2013-10-04 15:04:25 -05:00
mdipierro
700fd846a8 fixed a problem with grid 2013-10-04 14:56:16 -05:00
mdipierro
72a7643cde fixed issue 1704, groups in ldap, thanks Peter Gastinger 2013-10-04 14:41:19 -05:00
mdipierro
6b0177979f fixed issue 1705, sorting of model, thanks Anthony 2013-10-04 14:39:32 -05:00
mdipierro
7eb67fe6fa fields with readable=False should not be exportable from grid 2013-10-04 00:16:30 -05:00
mdipierro
5be65e8bd4 fixed issue 1697:gae memcached is not storing anything, thanks Yair 2013-10-03 08:40:19 -05:00
mdipierro
46903a3732 fixed issue 1698:Application Name Containing a Period . Not Supported, thanks Anton 2013-10-03 08:37:42 -05:00
mdipierro
c5b9b4d723 fixed issue 1700:DAL contains is not working on MSSQL 2013-10-03 08:33:57 -05:00
mdipierro
302a985aa7 fixed self.settings.table_<> 2013-10-03 08:19:34 -05:00
mdipierro
21a11ec47a removing garbage from admin it.py 2013-10-02 18:44:42 -05:00
mdipierro
814f4f4b4c fixed issue 1701:Restore menu/page after end of impersonation, thanks kmouts 2013-10-02 18:36:32 -05:00
mdipierro
87eeaaf028 fixed bug in stripe.py 2013-10-02 13:29:14 -05:00
mdipierro
b44aefc384 fixed some problems with StripeForm 2013-10-02 11:42:02 -05:00
mdipierro
e2c940532d new gluon.contrib.strip.StripeForm for PCI compliant payments 2013-10-02 11:06:30 -05:00
Massimo
66d6b3b511 fixed issue 1696:webclient not built to handle lists, thanks Yair 2013-10-01 15:25:34 -05:00
mdipierro
f0010f320e Merge pull request #233 from niphlod/issue/taskbar
fixed import for taskbar
2013-10-01 13:18:01 -07:00
niphlod
f092530a8c fixed import for taskbar 2013-10-01 20:46:00 +02:00
mdipierro
11a9fa345d Merge pull request #232 from timrichardson/issue/1695
Updated jquery-ui css resource to fix 404 error
2013-10-01 08:04:16 -07:00
Tim Richardson
a1c2019960 Updated jquery-ui css resource to fix 404 error 2013-09-29 06:47:19 +10:00
mdipierro
96e17ff1db SQLFORM.grid(...,ignore_common_filters=True) 2013-09-27 13:08:02 -05:00
mdipierro
4292cf38d9 more translations, thanks Vladyslav 2013-09-26 21:26:55 -05:00
mdipierro
fcba1650a0 Merge pull request #231 from ilvalle/cm-3.18
codemirror 3.18 with enabled the fullscreen addon
2013-09-26 14:37:47 -07:00
Paolo
ddf1998d49 codemirror 3.18 with enabled the fullscreen addon 2013-09-26 21:52:53 +02:00
Massimo
633acffd28 made form session logic backward compatible 2013-09-26 13:35:39 -05:00
Massimo
09ba525f2e possible fix to issue 1688, support for multiple forms with same formname in different browser pages 2013-09-26 11:26:08 -05:00
mdipierro
a8cbb1590d Translation of An 2013-09-26 07:56:49 -05:00
mdipierro
89971d1cb5 revised markmin.html, thanks Vladyslav 2013-09-25 19:54:42 -05:00
mdipierro
35180d61fa simplification in auth multilogin 2013-09-25 09:44:37 -05:00
mdipierro
8954d90ada minor change in languages/it.py 2013-09-25 09:08:40 -05:00
mdipierro
c0d399680e Merge pull request #227 from letolabs/fix_min_web2py
Update location of handlers so that make_min_web2py.py works again
2013-09-24 15:24:39 -07:00
mdipierro
528dd912d8 Merge pull request #228 from niphlod/enhancement/trapped_links
pass the correct element when trapping links
2013-09-24 15:23:07 -07:00
niphlod
cb6ae0516c pass the correct element when trapping links 2013-09-25 00:09:19 +02:00
Jonathan "Duke" Leto
4e1ad9bfa8 Update location of handlers to that make_min_web2py.py works again
The location of the handlers changed in 07f74c6362 and since then
this error blocked the creation of a minizimed web2py instance:

IOError: [Errno 2] No such file or directory: 'fcgihandler.py'
2013-09-24 13:44:38 -07:00
Massimo
6bea258722 update pbkdf2_ctypes.py to upstream, thanks Michele 2013-09-24 13:52:52 -05:00
mdipierro
554a52d548 Merge pull request #226 from michele-comitini/master
update pbkdf2_ctypes.py to upstream
2013-09-24 11:51:34 -07:00
Massimo
1a17655ef1 fixed line not found issues in set breakpoint, thanks Mariano 2013-09-24 13:51:08 -05:00
Massimo
5af2db1ff8 Merge branch 'master' of github.com:web2py/web2py 2013-09-24 13:48:49 -05:00
Massimo
a8567ae9ed syncing 2013-09-24 13:45:14 -05:00
mdipierro
40925165e6 Merge pull request #225 from reingart/master
fixed line not found issues in set breakpoint (linecache patch, used by the debugger)
2013-09-24 11:44:22 -07:00
mdipierro
eb4942a38d Merge pull request #224 from niphlod/enhancement/sessions2trash.py
session2trash.py: easier to use within a module, e.g. in the scheduler
2013-09-24 11:41:29 -07:00
Massimo
5f9d8a9cc2 no more if len(dpost) 2013-09-24 13:37:25 -05:00
Massimo
b67141b1ef fixed problem with ENABLED/DISABLED, issue 1689 2013-09-24 13:29:54 -05:00
Michele Comitini
9f69b9aa42 still support for python2.5 2013-09-24 20:01:51 +02:00
Michele Comitini
18cdade705 added support for python2.5 2013-09-24 18:37:10 +02:00
Michele Comitini
7eb8a604bd update pbkdf2_ctypes.py to upstream 2013-09-24 18:03:49 +02:00
Mariano Reingart
d55470f753 fixed line not found issues in set breakpoint (linecache patch, used by the debugger) 2013-09-24 02:52:01 -03:00
mdipierro
c4042dc475 improved es.py, thanks mcamel and Vladyslav 2013-09-23 16:33:06 -05:00
niphlod
0688c86dee easier to use within a module, e.g. in the scheduler 2013-09-23 22:41:37 +02:00
mdipierro
d111f331ca fixed issue 1196:add language subfolders, thanks jamarcer 2013-09-23 14:54:29 -05:00
mdipierro
f622f2936a Merge pull request #223 from robertop23/master
Fixes and improvements in admin editor
2013-09-23 08:35:05 -07:00
mdipierro
4e017d3ffa Merge pull request #222 from charleslaw/master
Various Minor Auth Additions
2013-09-23 08:34:28 -07:00
Roberto Perdomo
2ebf0d12ed Fix lost flash message in case of error when save editor (crtl-s). Change Esc to Ctrl-Esc to exit from Fullscreen mode, because this cause collision with the Vim mode (Esc key). Add a select into the config button to select 'default', 'vim' or 'emacs' editor 2013-09-22 18:36:28 -04:30
mdipierro
d547a9d6ea added nl, es plural rules, thanks Vladyslav 2013-09-22 10:10:28 -05:00
mdipierro
afdb028070 R-2.6.4 2013-09-21 20:42:19 -05:00
mdipierro
80d4615f32 R-2.6.4 2013-09-21 20:24:31 -05:00
Charles Law
cb7753af2a add a hook for a pre registration message 2013-09-21 19:48:21 -04:00
mdipierro
5a12a7fb31 manually committed pull 221, update vars only if FieldStorage holds actually something, thanks Niphlod 2013-09-21 18:15:27 -05:00
Charles Law
d4bceef5b4 Send username/email in verification email 2013-09-21 18:47:41 -04:00
Charles Law
931082f426 add password class to 2nd password registration field 2013-09-21 18:35:34 -04:00
Charles Law
333fb4ebd8 allow for a multi_login option that accepts both emails and usernames 2013-09-21 18:21:34 -04:00
Charles Law
27b6319f2e have more descriptive messages for username issues 2013-09-21 15:42:10 -04:00
Charles Law
70d8b2d755 show message when an email is already taken 2013-09-21 15:16:06 -04:00
mdipierro
17c10b8a45 things got out of sync 2013-09-20 21:28:26 -05:00
mdipierro
f8e2c8e319 new validator IS_LIST_OF_EMAILS 2013-09-20 21:17:05 -05:00
mdipierro
9ea82fdaaf fixed issue 1686:admin editor files menu hidden when codemirror is in fullscreen mode, thanks Paolo Caruccio 2013-09-20 20:57:29 -05:00
mdipierro
3d01a83c85 Merge pull request #220 from bunnyhugdev/master
Edited cookie handling code when using a db to store sessions
2013-09-20 12:51:49 -07:00
Joel Rathgaber
13f8b1a10c Edited cookie handling code when using a db to store sessions
- Session id cookie is always sent back to client in response
- When no cookie is sent in as a request, a new session id is created
2013-09-20 13:29:50 -06:00
Massimo
f78e172eda fixed issue 1673, propagation for format in archive tables 2013-09-20 12:47:15 -05:00
mdipierro
bd452f90b2 session._fixup_before_save 2013-09-20 08:36:52 -05:00
mdipierro
2b1f150f02 relaxed REST conditions 2013-09-19 22:18:45 -05:00
mdipierro
e7a9457249 fixed problem with widget and list:string 2013-09-19 22:03:37 -05:00
mdipierro
d3ab2e73d5 support for driver mysql.connector, thank you Josiel Santos 2013-09-19 21:44:12 -05:00
mdipierro
860f40ca63 added support for 3letter language files, issue 1680, thanks Fran 2013-09-19 21:33:31 -05:00
mdipierro
59a7db56a4 fixed major problem with persistance of session.flash 2013-09-19 20:51:11 -05:00
mdipierro
01e5107a96 possible fix to issues 1682, REST and DELETE 2013-09-19 18:33:27 -05:00
mdipierro
8765dbbe0f an attempt to fix 1685 2013-09-19 18:26:35 -05:00
mdipierro
d125b0b95b expires can be str or datetime 2013-09-19 18:03:35 -05:00
mdipierro
1d2fc4b8f5 simpler logic in parse POST but not functional difference 2013-09-19 17:47:29 -05:00
mdipierro
146ea115bf Merge pull request #219 from niphlod/enhancement/ajax_page_notarget
fixed issue when target is none. removed useless file in admin/static/js
2013-09-19 14:44:03 -07:00
niphlod
4f44188997 fixed issue when target is not none. removed useless file in admin/static/js 2013-09-19 21:52:45 +02:00
mdipierro
ac5fb303eb Merge pull request #218 from mpranjic/masterfix
startswith, endswith and contains for upload fields
2013-09-19 12:10:07 -07:00
mdipierro
31a14997f8 Merge pull request #216 from ilvalle/ajax_title
Set document title when an ajax fragment has got a <title> element
2013-09-19 12:09:01 -07:00
mpranjic
4cd4ff2c5e startswith, endswith and contains for upload fields 2013-09-19 10:58:23 +02:00
Massimo
26ef508966 added some missing files, is admin/static/js/jquery-1.10.0.min.map correct? 2013-09-18 14:37:28 -05:00
Paolo
28b4badb9a concatenation of filter and find for a better <title> discovery 2013-09-18 17:33:54 +02:00
mdipierro
8e2e2420b0 fixed style of edit in admin 2013-09-18 10:18:31 -05:00
mdipierro
67349627f4 Merge pull request #214 from niphlod/fix/admin_emmet
fixes keyboard shortcuts in admin when modifying js or css files
2013-09-18 08:05:49 -07:00
mdipierro
cfe825f94a Merge pull request #213 from spametki/master
Fix imap insert multipart detection
2013-09-18 08:05:05 -07:00
mdipierro
53e79915fa skip virtual fields on AttributeError 2013-09-18 08:29:31 -05:00
ilvalle
9fb5f688ed Set document title if an ajax fragment has a <title> element 2013-09-18 09:15:06 +02:00
mdipierro
c2cdae0615 new setup_exe.py, thanks Niphlod 2013-09-17 08:31:01 -05:00
mdipierro
2516bb59a1 fixed issue 1679:auth.navbar() duplicates first link if mode is 'default', thanks wkl 2013-09-16 08:55:43 -05:00
mdipierro
13c78fae58 R-2.6.3 2013-09-15 12:00:13 -05:00
mdipierro
91c0a31800 R-2.6.3 2013-09-15 11:51:01 -05:00
mdipierro
277137c8e6 R-2.6.3 2013-09-15 11:48:32 -05:00
mdipierro
4556a355a2 fixed a problem with CRYPT password length 2013-09-15 11:46:46 -05:00
mdipierro
7dafb07438 added a extra level of protection for long passwords, even if IS_LENGTH validator is missing 2013-09-15 09:40:15 -05:00
niphlod
3c8e7a1364 fixes keyboard shortcuts in admin when modifying js or css files 2013-09-15 11:23:58 +02:00
spametki
921cd46c10 Fix imap insert multipart detection 2013-09-14 16:03:41 -03:00
234 changed files with 5058 additions and 2982 deletions

1
.gitignore vendored
View File

@@ -55,3 +55,4 @@ applications/admin/cron/cron.master
HOWTO-web2py-devel
*.sublime-project
*.sublime-workspace
.idea/*

View File

@@ -1,4 +1,19 @@
## 2.6.1
## 2.7.1 - 2.7.2
- jQuery 1.10.2
- codemirror 3.18, thanks Paolo
- namespaces in T("Welcome", ns="namespace"), thanks jamarcer (experimental)
- more Auth options, thanks Charles
- more admin configuration, thanks Roberto
- new gluon.contrib.strip.StripeForm for PCI compliant payments
- webclient can hendle lists, thanks Yair
- allows SQLFORM.grid(...,ignore_common_filters=True)
- more translations, thanks Vladyslav
- better session2trash.py, works with scheduler, thanks niphlod
- fixed problem with ENABLED/DISABLED
- many bug fixes, thanks niphlod, michele, anthony, roberto, tim, and others
## 2.6.1 - 2.6.4
Attention all users: For pre 2.6 applications to work with web2py >=2.6, you must copy static/js/web2py.js, controllers/appadmin.py, and views/appadmin.html from the welcome app to your own apps (all of them).
@@ -38,6 +53,8 @@ Attention MySQL users: The length of string fields changed from 255 to 512 bytes
- speedup for define_table, thanks Michele
- settings.cfg to admin, thanks Paolo
- many bugs fixed, thanks Niphlod, Michele, Roberto, Jonathan, and many others
- 2.6,3 specifically fixed a possible DoS vulnerability
- 2.6.4 specifically fixes major problem introduced in 2.6.1 with session logic
## 2.5.2

View File

@@ -30,7 +30,7 @@ update:
echo "remember that pymysql was tweaked"
src:
### Use semantic versioning
echo 'Version 2.6.2-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
echo 'Version 2.7.3-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
### rm -f all junk files
make clean
### clean up baisc apps
@@ -81,6 +81,7 @@ app:
cp -r applications/examples ../web2py_osx/web2py/web2py.app/Contents/Resources/applications
cp applications/__init__.py ../web2py_osx/web2py/web2py.app/Contents/Resources/applications
cd ../web2py_osx; zip -r web2py_osx.zip web2py
mv ../web2py_osx/web2py_osx.zip .
win:
python2.7 -c 'import compileall; compileall.compile_dir("gluon/")'

View File

@@ -1 +1 @@
Version 2.6.2-stable+timestamp.2013.09.13.17.43.10
Version 2.7.3-stable+timestamp.2013.10.11.18.10.01

View File

@@ -33,7 +33,7 @@ class Servers:
@staticmethod
def wsgiref(app, address, **options): # pragma: no cover
from wsgiref.simple_server import make_server, WSGIRequestHandler
options = {}
class QuietHandler(WSGIRequestHandler):
def log_request(*args, **kw):
pass
@@ -71,6 +71,7 @@ class Servers:
@staticmethod
def paste(app, address, **options):
options = {}
from paste import httpserver
from paste.translogger import TransLogger
httpserver.serve(app, host=address[0], port=address[1], **options)
@@ -90,10 +91,12 @@ class Servers:
@staticmethod
def gevent(app, address, **options):
options = options['options']
workers = options.workers
from gevent import pywsgi
from gevent.pool import Pool
pywsgi.WSGIServer(address, app, spawn='workers' in options and Pool(
int(options.workers)) or 'default').serve_forever()
pywsgi.WSGIServer(address, app, spawn=workers and Pool(
int(options.workers)) or 'default', log=None).serve_forever()
@staticmethod
def bjoern(app, address, **options):
@@ -130,6 +133,7 @@ class Servers:
@staticmethod
def gunicorn(app, address, **options):
options = {}
from gunicorn.app.base import Application
config = {'bind': "%s:%d" % address}
config.update(options)
@@ -176,27 +180,6 @@ class Servers:
s = wsgi.WSGIServer(callable=app, bind="%s:%d" % address)
s.start()
def run(servername, ip, port, softcron=True, logging=False, profiler=None):
if servername == 'gevent':
from gevent import monkey
monkey.patch_all()
elif servername == 'eventlet':
import eventlet
eventlet.monkey_patch()
import gluon.main
if logging:
application = gluon.main.appfactory(wsgiapp=gluon.main.wsgibase,
logfilename='httpserver.log',
profiler_dir=profiler)
else:
application = gluon.main.wsgibase
if softcron:
from gluon.settings import global_settings
global_settings.web2py_crontype = 'soft'
getattr(Servers, servername)(application, (ip, int(port)))
def mongrel2_handler(application, conn, debug=False):
"""
@@ -303,6 +286,30 @@ def mongrel2_handler(application, conn, debug=False):
req, data, code=code, status=status, headers=headers)
def run(servername, ip, port, softcron=True, logging=False, profiler=None,
options=None):
if servername == 'gevent':
from gevent import monkey
monkey.patch_all()
elif servername == 'eventlet':
import eventlet
eventlet.monkey_patch()
import gluon.main
if logging:
application = gluon.main.appfactory(wsgiapp=gluon.main.wsgibase,
logfilename='httpserver.log',
profiler_dir=profiler)
else:
application = gluon.main.wsgibase
if softcron:
from gluon.settings import global_settings
global_settings.web2py_crontype = 'soft'
getattr(Servers, servername)(application, (ip, int(port)), options=options)
def main():
usage = "python anyserver.py -s tornado -i 127.0.0.1 -p 8000 -l -P"
try:
@@ -339,14 +346,15 @@ def main():
help='port number')
parser.add_option('-w',
'--workers',
default='',
default=None,
dest='workers',
help='number of workers number')
(options, args) = parser.parse_args()
print 'starting %s on %s:%s...' % (
options.server, options.ip, options.port)
run(options.server, options.ip, options.port,
logging=options.logging, profiler=options.profiler_dir)
logging=options.logging, profiler=options.profiler_dir,
options=options)
if __name__ == '__main__':
main()

View File

@@ -54,7 +54,7 @@ elif (request.application == 'admin' and not session.authorized) or \
redirect(URL('admin', 'default', 'index',
vars=dict(send=URL(args=request.args, vars=request.vars))))
else:
response.subtitle = 'Database Administration (appadmin)'
response.subtitle = T('Database Administration (appadmin)')
menu = True
ignore_rw = True

View File

@@ -108,7 +108,7 @@ def index():
if session.authorized:
redirect(send)
elif request.vars.password:
if verify_password(request.vars.password):
if verify_password(request.vars.password[:1024]):
session.authorized = True
login_record(True)
@@ -197,7 +197,7 @@ def site():
class IS_VALID_APPNAME(object):
def __call__(self, value):
if not re.compile('\w+').match(value):
if not re.compile('^\w+$').match(value):
return (value, T('Invalid application name'))
if not request.vars.overwrite and \
os.path.exists(os.path.join(apath(r=request), value)):
@@ -494,6 +494,7 @@ def enable():
if is_gae:
return SPAN(T('Not supported'), _style='color:yellow')
elif os.path.exists(filename):
os.unlink(filename)
return SPAN(T('Disable'), _style='color:green')
else:
safe_open(filename, 'wb').write('disabled: True\ntime-disabled: %s' % request.now)
@@ -562,14 +563,14 @@ def edit():
# Load json only if it is ajax edited...
app = get_app(request.vars.app)
app_path = apath(app, r=request)
editor_defaults={'theme':'web2py'}
editor_defaults={'theme':'web2py', 'editor': 'default'}
config = Config(os.path.join(request.folder, 'settings.cfg'),
section='editor', default_values=editor_defaults)
preferences = config.read()
if not(request.ajax):
# return the scaffolding, the rest will be through ajax requests
response.title = T('Editing %s' % app)
response.title = T('Editing %s') % app
editarea_preferences = {}
editarea_preferences['FONT_SIZE'] = '10'
editarea_preferences['FULL_SCREEN'] = 'false'
@@ -588,7 +589,7 @@ def edit():
response.headers["web2py-component-flash"] = T('Preferences saved correctly')
else:
response.headers["web2py-component-flash"] = T('Preferences saved on session only')
response.headers["web2py-component-command"] = "update_theme('%s'); jQuery('a[href=#editor_settings] button.close').click();" % config.read()['theme']
response.headers["web2py-component-command"] = "update_theme('%s');update_editor('%s');jQuery('a[href=#editor_settings] button.close').click();" % (config.read()['theme'], config.read()['editor'])
return
else:
details = {'filename':'settings', 'id':'editor_settings', 'force': False}
@@ -604,7 +605,7 @@ def edit():
path = abspath(filename)
else:
path = apath(filename, r=request)
# Try to discover the file type
# Try to discover the file type
if filename[-3:] == '.py':
filetype = 'python'
elif filename[-5:] == '.html':
@@ -700,7 +701,6 @@ def edit():
offset and ' ' +
T('at char %s', offset) or '',
PRE(str(e)))
if data_or_revert and request.args[1] == 'modules':
# Lets try to reload the modules
try:

View File

@@ -43,14 +43,14 @@ def commit():
app = request.args(0)
path = apath(app, r=request)
repo = hg_repo(path)
form = FORM('Comment:', INPUT(_name='comment', requires=IS_NOT_EMPTY()),
form = FORM(T('Comment:'), INPUT(_name='comment', requires=IS_NOT_EMPTY()),
INPUT(_type='submit', _value=T('Commit')))
if form.accepts(request.vars, session):
oldid = repo[repo.lookup('.')]
addremove(repo)
repo.commit(text=form.vars.comment)
if repo[repo.lookup('.')] == oldid:
response.flash = 'no changes'
response.flash = T('no changes')
try:
files = TABLE(*[TR(file) for file in repo[repo.lookup('.')].files()])
changes = TABLE(TR(TH('revision'), TH('description')))
@@ -75,7 +75,7 @@ def revision():
form = FORM(INPUT(_type='submit', _value=T('Revert')))
if form.accepts(request.vars):
hg.update(repo, revision)
session.flash = "reverted to revision %s" % ctx.rev()
session.flash = T("reverted to revision %s") % ctx.rev()
redirect(URL('default', 'design', args=app))
return dict(
files=ctx.files(),

View File

@@ -7,31 +7,35 @@
'%s %%{row} updated': '%s filas actualizadas',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'(requires internet access, experimental)': '(requiere acceso a internet, experimental)',
'(something like "it-it")': '(algo como "it-it")',
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)',
'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page',
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
'A new version of web2py is available': 'Hay una nueva versión de web2py disponible',
'A new version of web2py is available: %s': 'Hay una nueva versión de web2py disponible: %s',
'About': 'acerca de',
'About application': 'Acerca de la aplicación',
'additional code for your application': 'código adicional para su aplicación',
'Additional code for your application': 'Additional code for your application',
'admin disabled because no admin password': ' por falta de contraseña',
'Additional code for your application': 'Código adicional para su aplicación',
'admin disabled because no admin password': 'admin deshabilitado por falta de contraseña',
'admin disabled because not supported on google app engine': 'admin deshabilitado, no es soportado en GAE',
'admin disabled because unable to access password file': 'admin deshabilitado, imposible acceder al archivo con la contraseña',
'Admin is disabled because insecure channel': 'Admin deshabilitado, el canal no es seguro',
'Admin is disabled because unsecure channel': 'Admin deshabilitado, el canal no es seguro',
'Admin language': 'Admin language',
'administrative interface': 'administrative interface',
'Admin language': 'Lenguaje de administración',
'administrative interface': 'interfaz administrativa',
'Administrator Password:': 'Contraseña del Administrador:',
'An error occured, please %s the page': 'An error occured, please %s the page',
'An error occured, please %s the page': 'Ha ocurrido un error, por favor %s la página',
'and rename it (required):': 'y renombrela (requerido):',
'and rename it:': ' y renombrelo:',
'appadmin': 'appadmin',
'appadmin is disabled because insecure channel': 'admin deshabilitado, el canal no es seguro',
'application "%s" uninstalled': 'aplicación "%s" desinstalada',
'application %(appname)s installed with md5sum: %(digest)s': 'application %(appname)s installed with md5sum: %(digest)s',
'application compiled': 'aplicación compilada',
'application is compiled and cannot be designed': 'la aplicación está compilada y no puede ser modificada',
'Application name:': 'Nombre de la aplicación:',
'are not used': 'are not used',
'are not used yet': 'are not used yet',
'Are you sure you want to delete file "%s"?': '¿Está seguro que desea eliminar el archivo "%s"?',
@@ -41,12 +45,13 @@
'Are you sure you want to uninstall application "%s"?': '¿Está seguro que desea desinstalar la aplicación "%s"?',
'Are you sure you want to upgrade web2py now?': '¿Está seguro que desea actualizar web2py ahora?',
'arguments': 'argumentos',
'at char %s': 'at char %s',
'at line %s': 'at line %s',
'at char %s': 'en el caracter %s',
'at line %s': 'en la línea %s',
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENCION: Inicio de sesión requiere una conexión segura (HTTPS) o localhost.',
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENCION: NO EJECUTE VARIAS PRUEBAS SIMULTANEAMENTE, NO SON THREAD SAFE.',
'ATTENTION: you cannot edit the running application!': 'ATENCION: no puede modificar la aplicación que se ejecuta!',
'Autocomplete': 'Autocomplete',
'Autocomplete Python Code': 'Autocompletar código Python',
'Available databases and tables': 'Bases de datos y tablas disponibles',
'back': 'atrás',
'breakpoint': 'breakpoint',
@@ -54,14 +59,17 @@
'browse': 'buscar',
'cache': 'cache',
'cache, errors and sessions cleaned': 'cache, errores y sesiones eliminados',
'can be a git repo': 'puede ser un repositorio git',
'Cannot be empty': 'No puede estar vacío',
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'No se puede compilar: hay errores en su aplicación. Depure, corrija errores y vuelva a intentarlo.',
'Cannot compile: there are errors in your app:': 'No se puede compilar: hay errores en su aplicación:',
'cannot create file': 'no es posible crear archivo',
'cannot upload file "%(filename)s"': 'no es posible subir archivo "%(filename)s"',
'Change admin password': 'cambie contraseña admin',
'change editor settings': 'cambiar la configuración del editor',
'Change Password': 'Cambie Contraseña',
'check all': 'marcar todos',
'Check for upgrades': 'buscar actualizaciones',
'Check to delete': 'Marque para eliminar',
'Checking for upgrades...': 'Buscando actulizaciones...',
'Clean': 'limpiar',
@@ -69,28 +77,30 @@
'click here for the administrative interface': 'haga clic aquí para usar la interfaz administrativa',
'Click row to expand traceback': 'Click row to expand traceback',
'click to check for upgrades': 'haga clic para buscar actualizaciones',
'click to open': 'click to open',
'click to open': 'click para abrir',
'Client IP': 'IP del Cliente',
'code': 'código',
'Code listing': 'Code listing',
'collapse/expand all': 'collapse/expand all',
'commit (mercurial)': 'commit (mercurial)',
'Code listing': 'Listado de código',
'collapse/expand all': 'contraer/expandir todo',
'commit (mercurial)': 'confirmar (mercurial)',
'Compile': 'compilar',
'compiled application removed': 'aplicación compilada removida',
'continue': 'continue',
'continue': 'continuar',
'Controllers': 'Controladores',
'controllers': 'controladores',
'Count': 'Count',
'Create': 'crear',
'Create': 'Crear',
'create file with filename:': 'cree archivo con nombre:',
'Create new application using the Wizard': 'Create new application using the Wizard',
'Create new application using the Wizard': 'Crear nueva aplicación utilizando el asistente',
'create new application:': 'nombre de la nueva aplicación:',
'Create new simple application': 'Cree una nueva aplicación',
'Create/Upload': 'Create/Upload',
'created by': 'creado por',
'crontab': 'crontab',
'Current request': 'Solicitud en curso',
'Current response': 'Respuesta en curso',
'Current session': 'Sesión en curso',
'currently running': 'currently running',
'currently saved or': 'actualmente guardado o',
'customize me!': 'Adaptame!',
'data uploaded': 'datos subidos',
@@ -105,37 +115,52 @@
'delete': 'eliminar',
'delete all checked': 'eliminar marcados',
'delete plugin': 'eliminar plugin',
'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)',
'Delete this file (you will be asked to confirm deletion)': 'Elimine este fichero (se le pedirá confirmación)',
'Delete:': 'Elimine:',
'Deploy': 'Deploy',
'Deploy on Google App Engine': 'Instale en Google App Engine',
'Deploy to OpenShift': 'Instale en OpenShift',
'Description': 'Descripción',
'design': 'modificar',
'DESIGN': 'DISEÑO',
'Design for': 'Diseño para',
'Detailed traceback description': 'Detailed traceback description',
'details': 'detalles',
'direction: ltr': 'direction: ltr',
'Disable': 'Deshabilitar',
'docs': 'docs',
'done!': 'listo!',
'download layouts': 'download layouts',
'download plugins': 'download plugins',
'Download': 'Descargar',
'download files via http:': 'descargar archivos via http:',
'download layouts': 'descargar layouts',
'download plugins': 'descargar plugins',
'E-mail': 'Correo electrónico',
'EDIT': 'EDITAR',
'Edit': 'editar',
'Edit application': 'Editar aplicación',
'edit controller': 'editar controlador',
'edit controller:': 'edit controller:',
'Edit current record': 'Edite el registro actual',
'Edit Profile': 'Editar Perfil',
'edit views:': 'editar vistas:',
'Editing file': 'Editando archivo',
'Editing file "%s"': 'Editando archivo "%s"',
'Editing Language file': 'Editando archivo de lenguaje',
'Editing myclientapi': 'Editing myclientapi',
'Editing myemail': 'Editing myemail',
'Editing rbare': 'Editing rbare',
'Editing ul': 'Editing ul',
'Enterprise Web Framework': 'Armazón Empresarial para Internet',
'Error': 'Error',
'Error logs for "%(app)s"': 'Bitácora de errores en "%(app)s"',
'Error snapshot': 'Error snapshot',
'Error ticket': 'Error ticket',
'Errors': 'errores',
'Exception instance attributes': 'Atributos de la instancia de Excepción',
'Expand Abbreviation': 'Expand Abbreviation',
'export as csv file': 'exportar como archivo CSV',
'exposes': 'expone',
'exposes:': 'exposes:',
'exposes:': 'expone:',
'extends': 'extiende',
'failed to compile file because:': 'failed to compile file because:',
'failed to reload module': 'recarga del módulo ha fallado',
@@ -151,9 +176,10 @@
'file saved on %(time)s': 'archivo guardado %(time)s',
'file saved on %s': 'archivo guardado %s',
'filter': 'filter',
'Find Next': 'Find Next',
'Find Previous': 'Find Previous',
'Find Next': 'Buscar próximo',
'Find Previous': 'Bucar anterior',
'First name': 'Nombre',
'Frames': 'Frames',
'Functions with no doctests will result in [passed] tests.': 'Funciones sin doctests equivalen a pruebas [aceptadas].',
'Globals##debug': 'Globals',
'graph model': 'graph model',
@@ -166,6 +192,7 @@
'includes': 'incluye',
'insert new': 'inserte nuevo',
'insert new %s': 'inserte nuevo %s',
'inspect attributes': 'inspect attributes',
'Install': 'instalar',
'Installed applications': 'Aplicaciones instaladas',
'Interaction at %s line %s': 'Interaction at %s line %s',
@@ -175,10 +202,12 @@
'Invalid action': 'Acción inválida',
'Invalid email': 'Correo inválido',
'invalid password': 'contraseña inválida',
'invalid password.': 'invalid password.',
'Invalid Query': 'Consulta inválida',
'invalid request': 'solicitud inválida',
'invalid ticket': 'tiquete inválido',
'Key bindings': 'Key bindings',
'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin',
'language file "%(filename)s" created/updated': 'archivo de lenguaje "%(filename)s" creado/actualizado',
'Language files (static strings) updated': 'Archivos de lenguaje (cadenas estáticas) actualizados',
'languages': 'lenguajes',
@@ -188,13 +217,15 @@
'Last saved on:': 'Guardado en:',
'License for': 'Licencia para',
'loading...': 'cargando...',
'locals': 'locals',
'Locals##debug': 'Locals',
'Login': 'Inicio de sesión',
'login': 'inicio de sesión',
'Login to the Administrative Interface': 'Inicio de sesión para la Interfaz Administrativa',
'Logout': 'fin de sesión',
'Lost Password': 'Contraseña perdida',
'manage': 'manage',
'manage': 'gestionar',
'Manage': 'Gestionar',
'merge': 'combinar',
'Models': 'Modelos',
'models': 'modelos',
@@ -202,24 +233,31 @@
'modules': 'módulos',
'Name': 'Nombre',
'new application "%s" created': 'nueva aplicación "%s" creada',
'New application wizard': 'Asistente para nueva aplicación',
'new plugin installed': 'nuevo plugin instalado',
'New Record': 'Registro nuevo',
'new record inserted': 'nuevo registro insertado',
'New simple application': 'Nueva aplicación',
'next': 'next',
'next 100 rows': '100 filas siguientes',
'NO': 'NO',
'No databases in this application': 'No hay bases de datos en esta aplicación',
'No Interaction yet': 'No Interaction yet',
'no match': 'no encontrado',
'no package selected': 'no package selected',
'No ticket_storage.txt found under /private folder': 'No ticket_storage.txt found under /private folder',
'online designer': 'online designer',
'or alternatively': 'or alternatively',
'Or Get from URL:': 'O obtener desde una URL:',
'or import from csv file': 'o importar desde archivo CSV',
'or provide app url:': 'o provea URL de la aplicación:',
'or provide application url:': 'o provea URL de la aplicación:',
'Origin': 'Origen',
'Original/Translation': 'Original/Traducción',
'Overwrite installed app': 'sobreescriba aplicación instalada',
'Overwrite installed app': 'sobreescriba la aplicación instalada',
'Pack all': 'empaquetar todo',
'Pack compiled': 'empaquete compiladas',
'Pack custom': 'empaquetar personalizado',
'pack plugin': 'empaquetar plugin',
'PAM authenticated user, cannot change password here': 'usuario autenticado por PAM, no puede cambiar la contraseña aquí',
'Password': 'Contraseña',
@@ -233,9 +271,10 @@
'Plural-Forms:': 'Plural-Forms:',
'Powered by': 'Este sitio usa',
'previous 100 rows': '100 filas anteriores',
'Private files': 'Private files',
'private files': 'private files',
'Private files': 'Archivos privados',
'private files': 'archivos privados',
'Query:': 'Consulta:',
'Rapid Search': 'Rapid Search',
'record': 'registro',
'record does not exist': 'el registro no existe',
'record id': 'id de registro',
@@ -244,11 +283,14 @@
'Register': 'Registrese',
'Registration key': 'Contraseña de Registro',
'reload': 'reload',
'Reload routes': 'Reload routes',
'Remove compiled': 'eliminar compiladas',
'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s',
'Replace': 'Replace',
'Replace All': 'Replace All',
'Removed Breakpoint on %s at line %s': 'Eliminado punto de ruptura en %s en la línea %s',
'Replace': 'Reemplazar',
'Replace All': 'Reemplazar todos',
'request': 'request',
'Resolve Conflict file': 'archivo Resolución de Conflicto',
'response': 'response',
'restore': 'restaurar',
'return': 'return',
'revert': 'revertir',
@@ -256,27 +298,33 @@
'Rows in table': 'Filas en la tabla',
'Rows selected': 'Filas seleccionadas',
'rules are not defined': 'rules are not defined',
'Run tests in this file': 'Run tests in this file',
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')",
'Running on %s': 'Running on %s',
'Save': 'Save',
'save': 'guardar',
'Save file:': 'Save file:',
'Save via Ajax': 'Save via Ajax',
'Save file:': 'Guardar:',
'Save file: %s': 'Guardar: %s',
'Save via Ajax': 'Guardar via Ajax',
'Saved file hash:': 'Hash del archivo guardado:',
'selected': 'seleccionado(s)',
'session': 'session',
'session expired': 'sesión expirada',
'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s',
'Set Breakpoint on %s at line %s: %s': 'Establecer punto de ruptura en %s en la línea %s: %s',
'shell': 'shell',
'Site': 'sitio',
'some files could not be removed': 'algunos archivos no pudieron ser removidos',
'Start searching': 'Start searching',
'Start searching': 'Iniciar búsqueda',
'Start wizard': 'Iniciar asistente',
'state': 'estado',
'static': 'estáticos',
'Static': 'Static',
'static': 'estáticos',
'Static files': 'Archivos estáticos',
'step': 'step',
'stop': 'stop',
'submit': 'enviar',
'successful': 'successful',
'Submit': 'Submit',
'successful': 'exitoso',
'Sure you want to delete this object?': '¿Está seguro que desea eliminar este objeto?',
'table': 'tabla',
'Table name': 'Nombre de la tabla',
@@ -284,37 +332,41 @@
'Testing application': 'Probando aplicación',
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" es una condición como "db.tabla1.campo1==\'valor\'". Algo como "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.',
'the application logic, each URL path is mapped in one exposed function in the controller': 'la lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador',
'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller',
'The application logic, each URL path is mapped in one exposed function in the controller': 'La lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador',
'the data representation, define database tables and sets': 'la representación de datos, define tablas y conjuntos de base de datos',
'The data representation, define database tables and sets': 'The data representation, define database tables and sets',
'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates',
'The data representation, define database tables and sets': 'La representación de datos, define tablas y conjuntos de base de datos',
'The presentations layer, views are also known as templates': 'La capa de presentación, las vistas también son llamadas plantillas',
'the presentations layer, views are also known as templates': 'la capa de presentación, las vistas también son llamadas plantillas',
'There are no controllers': 'No hay controladores',
'There are no models': 'No hay modelos',
'There are no modules': 'No hay módulos',
'There are no plugins': 'There are no plugins',
'There are no private files': 'There are no private files',
'There are no plugins': 'No hay plugins',
'There are no private files': 'No hay archivos privados',
'There are no static files': 'No hay archivos estáticos',
'There are no translators, only default language is supported': 'No hay traductores, sólo el lenguaje por defecto es soportado',
'There are no views': 'No hay vistas',
'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app',
'These files are served without processing, your images go here': 'These files are served without processing, your images go here',
'These files are not served, they are only available from within your app': 'Estos archivos no son servidos, ellos solo estan disponibles para su aplicación',
'These files are served without processing, your images go here': 'Estos archivos son servidos sin procesar, sus imágenes van aquí',
'these files are served without processing, your images go here': 'estos archivos son servidos sin procesar, sus imágenes van aquí',
'This is the %(filename)s template': 'Esta es la plantilla %(filename)s',
'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.',
'Ticket': 'Tiquete',
'Ticket ID': 'Ticket ID',
'Timestamp': 'Timestamp',
'TM': 'MR',
'to previous version.': 'a la versión previa.',
'To create a plugin, name a file/folder plugin_[name]': 'Para crear un plugin, nombre un archivo/carpeta plugin_[nombre]',
'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:',
'to use the debugger!': 'to use the debugger!',
'toggle breakpoint': 'toggle breakpoint',
'Toggle Fullscreen': 'Toggle Fullscreen',
'toggle breakpoint': 'alternar punto de ruptura',
'Toggle Fullscreen': 'Alternar pantalla completa',
'Traceback': 'Traceback',
'translation strings for the application': 'cadenas de caracteres de traducción para la aplicación',
'Translation strings for the application': 'Translation strings for the application',
'Translation strings for the application': 'Cadenas de caracteres de traducción para la aplicación',
'try': 'intente',
'try something like': 'intente algo como',
'Try the mobile interface': 'Pruebe la interfaz móvil',
'try view': 'try view',
'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.',
'Unable to check for upgrades': 'No es posible verificar la existencia de actualizaciones',
'unable to create application "%s"': 'no es posible crear la aplicación "%s"',
@@ -332,9 +384,12 @@
'update': 'actualizar',
'update all languages': 'actualizar todos los lenguajes',
'Update:': 'Actualice:',
'upgrade now to %s': 'upgrade now to %s',
'upgrade web2py now': 'actualize web2py ahora',
'Upload': 'Upload',
'Upload': 'Subir',
'Upload & install packed application': 'Suba e instale aplicación empaquetada',
'Upload a package:': 'Subir un paquete:',
'Upload and install packed application': 'Suba e instale una aplicación empaquetada',
'upload application:': 'subir aplicación:',
'Upload existing application': 'Suba esta aplicación',
'upload file:': 'suba archivo:',
@@ -348,6 +403,7 @@
'view': 'vista',
'Views': 'Vistas',
'views': 'vistas',
'Web Framework': 'Web Framework',
'web2py is up to date': 'web2py está actualizado',
'web2py online debugger': 'web2py online debugger',
'web2py Recent Tweets': 'Tweets Recientes de web2py',

View File

@@ -11,6 +11,7 @@
'(requires internet access, experimental)': '(requires internet access, experimental)',
'(something like "it-it")': '(qualcosa simile a "it-it")',
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)',
'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page',
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
'A new version of web2py is available: %s': 'È disponibile una nuova versione di web2py: %s',
'About': 'informazioni',
@@ -55,6 +56,7 @@
'cannot create file': 'impossibile creare il file',
'cannot upload file "%(filename)s"': 'impossibile caricare il file "%(filename)s"',
'Change admin password': 'change admin password',
'change editor settings': 'change editor settings',
'change password': 'cambia password',
'check all': 'controlla tutto',
'Check for upgrades': 'check for upgrades',
@@ -76,6 +78,7 @@
'create file with filename:': 'crea un file col nome:',
'create new application:': 'create new application:',
'Create new simple application': 'Crea nuova applicazione',
'Create/Upload': 'Create/Upload',
'created by': 'creato da',
'crontab': 'crontab',
'Current request': 'Richiesta (request) corrente',
@@ -120,17 +123,14 @@
'edit profile': 'modifica profilo',
'Edit This App': 'Modifica questa applicazione',
'edit views:': 'modifica viste (view):',
'Editing bigul': 'Editing bigul',
'Editing file "%s"': 'Modifica del file "%s"',
'Editing italo': 'Editing italo',
'Editing italo3': 'Editing italo3',
'Editing Language file': 'Modifica file linguaggio',
'Editing %s': 'Editing %s',
'Enterprise Web Framework': 'Enterprise Web Framework',
'Error logs for "%(app)s"': 'Log degli errori per "%(app)s"',
'Error snapshot': 'Error snapshot',
'Error ticket': 'Error ticket',
'Errors': 'errori',
'Exception instance attributes': 'Exception instance attributes',
'Exit Fullscreen': 'Exit Fullscreen',
'Expand Abbreviation': 'Expand Abbreviation',
'export as csv file': 'esporta come file CSV',
'exposes': 'espone',

View File

@@ -1,5 +1,7 @@
#!/usr/bin/env python
{
# "singular form (0)": ["first plural form (1)", "second plural form (2)", ...],
'останній': ['останні','останніх'],
'файл': ['файли','файлів'],
'твіт': ['твіти','твітів'],
}

View File

@@ -8,13 +8,16 @@
'%s': '%s',
'%s %%{row} deleted': 'Вилучено %s %%{рядок}',
'%s %%{row} updated': 'Вилучено %s %%{рядок}',
'%s Recent Tweets': '%s останніх твітів',
'%s Recent Tweets': '%s %%{останній} %%{твіт}',
'%s students registered': '%s студентів зареєстровано',
'%Y-%m-%d': '%Y/%m/%d',
'%Y-%m-%d %H:%M:%S': '%Y/%m/%d %H:%M:%S',
'(requires internet access)': '(потрібно мати доступ в інтернет)',
'(requires internet access, experimental)': '(потрібно мати доступ в інтернет, експериментально)',
'(something like "it-it")': '(щось схоже на "uk-ua")',
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(не існує файлу **gluon/contrib/plural_rules/%s.py**)',
'@markmin\x01An error occured, please [[reload %s]] the page': 'Сталась помилка, будь-ласка [[переватажте %s]] сторінку',
"@markmin\x01Mercurial Version Control System Interface[[NEWLINE]]for application '%s'": "Інтерфейс системи контролю версій Mercurial[[NEWLINE]]для додатку '%s'",
'@markmin\x01Searching: **%s** %%{file}': 'Знайдено: **%s** %%{файл}',
'Abort': 'Припинити',
'About': 'Про',
@@ -55,6 +58,7 @@
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': "УВАГА: Вхід потребує надійного (HTTPS) з'єднання або запуску на локальному комп'ютері.",
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ОБЕРЕЖНО: ТЕСТУВАННЯ НЕ Є ПОТОКО-БЕЗПЕЧНИМ, ТОЖ НЕ ЗАПУСКАЙТЕ ДЕКІЛЬКА ТЕСТІВ ОДНОЧАСНО.',
'ATTENTION: you cannot edit the running application!': 'УВАГА: Ви не можете редагувати додаток, який зараз виконуєте!',
'Autocomplete Python Code': 'Автозавершення коду на Python',
'Available databases and tables': 'Доступні бази даних та таблиці',
'back': '<< назад',
'bad_resource': 'поганий_ресурс',
@@ -75,6 +79,7 @@
'cannot create file': 'не можу створити файл',
'cannot upload file "%(filename)s"': 'не можу завантажити файл "%(filename)s"',
'Change admin password': 'Змінити пароль адміністратора',
'change editor settings': 'змінити налаштування редактора',
'check all': 'відмітити всі',
'Check for upgrades': 'Перевірити оновлення',
'Check to delete': 'Помітити на вилучення',
@@ -89,7 +94,9 @@
'Code listing': 'Лістинг',
'collapse/expand all': 'згорнути/розгорнути все',
'Command': 'Команда',
'Comment:': 'Пояснення:',
'Commit': 'Комміт',
'Commit form': 'Commit form',
'Compile': 'Компілювати',
'compiled application removed': 'скомпільований додаток вилучено',
'Condition': 'Умова',
@@ -103,6 +110,7 @@
'create file with filename:': 'створити файл з назвою:',
'create plural-form': 'створити форму множини',
'Create rules': 'Створити правила',
'Create/Upload': 'Створити/Завантажити',
'created by': 'Автор:',
'Created On': 'Створено в',
'crontab': 'таблиця cron',
@@ -150,8 +158,10 @@
'edit all': 'редагувати всі',
'Edit application': 'Налаштування додатку',
'edit controller': 'редагувати контролер',
'edit controller:': 'редагувати контролер:',
'Edit current record': 'Редагувати поточний запис',
'edit views:': 'редагувати відображення (views):',
'Editing %s': 'Редагується %s',
'Editing file "%s"': 'Редагується файл "%s"',
'Editing Language file': 'Редагується файл перекладу',
'Editing Plural Forms File': 'Редагується файл форм множини',
@@ -166,6 +176,7 @@
'Exception %(extype)s: %(exvalue)s': 'Виключення %(extype)s: %(exvalue)s',
'Exception %s': 'Виключення %s',
'Exception instance attributes': 'Атрибути примірника класу Exception (виключення)',
'Exit Fullscreen': 'Вийти з повноекранного режиму',
'Expand Abbreviation': 'Розгорнути абревіатуру',
'export as csv file': 'експортувати як файл csv',
'exposes': 'обслуговує',
@@ -186,6 +197,8 @@
'file saved on %s': 'файл збережено в %s',
'Filename': "Ім'я файлу",
'filter': 'фільтр',
'Find Next': 'Шукати наступний',
'Find Previous': 'Шукати попередній',
'Frames': 'Стек викликів',
'Functions with no doctests will result in [passed] tests.': 'Функції, в яких відсутні док-тести відносяться до функцій, які успішно пройшли тести.',
'GAE Email': 'Ел.пошта GAE',
@@ -201,6 +214,7 @@
'Google App Engine Deployment Interface': 'Інтерфейс розгортання Google App Engine',
'Google Application Id': 'Ідентифікатор Google Application',
'Goto': 'Перейти до',
'graph model': 'графова модель',
'Help': 'Допомога',
'Hide/Show Translated strings': 'Сховати/показати ВЖЕ ПЕРЕКЛАДЕНІ рядки',
'Hits': 'Спрацьовувань',
@@ -208,7 +222,7 @@
'honored only if the expression evaluates to true': 'точка зупинки активується тільки за істинності умови',
'If start the downgrade, be patient, it may take a while to rollback': 'Запустивши повернення на попередню версію, будьте терплячими, це може зайняти трохи часу',
'If start the upgrade, be patient, it may take a while to download': 'Запустивши оновлення, будьте терплячими, потрібен час для завантаження необхідних даних',
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Якщо в наданому вище звіті присутня позначка про помилку (ticket number), то це вказує на збій у виконанні контролера ще до початку запуску док-тестів. Це, зазвичай, сигналізує про помилку вирівнювання тексту програми (indention error) або помилку за межами функції (error outside function code). Зелений заголовок сигналізує, що всі тести (з наявних) пройшли успішно. В цьому випадку результат тестів показано не буде.',
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Якщо в наданому вище звіті присутня позначка про помилку (ticket number), то це вказує на збій у виконанні контролера ще до початку запуску док-тестів. Це, зазвичай, сигналізує про помилку вирівнювання тексту програми (indention error) або помилку за межами функції (error outside function code).\n\t\tЗелений заголовок сигналізує, що всі тести (з наявних) пройшли успішно. В цьому випадку результат тестів показано не буде.',
'Import/Export': 'Імпорт/Експорт',
'In development, use the default Rocket webserver that is currently supported by this debugger.': 'Під час розробки , використовуйте вбудований веб-сервер Rocket, він найкраще налаштований на спільну роботу з інтерактивним ладначем.',
'includes': 'включає',
@@ -245,6 +259,8 @@
'License for': 'Ліцензія додатку',
'Line number': '№ рядка',
'LineNo': '№ рядка',
'lists by exception': 'список виключень (exceptions)',
'lists by ticket': 'список позначок (tickets)',
'loading...': 'завантаження...',
'locals': 'локальні',
'Locals##debug': 'Локальні змінні',
@@ -253,6 +269,7 @@
'Login to the Administrative Interface': 'Вхід в адміністративний інтерфейс',
'Logout': 'Вихід',
'Main Menu': 'Основне меню',
'Manage': 'Керувати',
'Manage Admin Users/Students': 'Адміністратор керування користувачами/студентами',
'Manage Students': 'Керувати студентами',
'Match Pair': 'Знайти пару',
@@ -282,6 +299,7 @@
'No databases in this application': 'Даний додаток не використовує бази даних',
'No Interaction yet': 'Ладнач не активовано',
'no match': 'співпадань нема',
'no package selected': 'пакет не вибрано',
'no permission to uninstall "%s"': 'нема прав на вилучення (uninstall) "%s"',
'No ticket_storage.txt found under /private folder': 'В каталозі /private відсутній файл ticket_storage.txt',
'Not Authorized': 'Не дозволено',
@@ -290,11 +308,14 @@
'online designer': 'дизайнер БД',
'OpenShift Deployment Interface': 'OpenShift: Інтерфейс розгортання',
'OpenShift Output': 'Вивід OpenShift',
'or alternatively': 'або альтернативно',
'Or Get from URL:': 'Або Отримати з мережі (ч/з URL):',
'or import from csv file': 'або імпортувати через csv-файл',
'Original/Translation': 'Оригінал/переклад',
'Overwrite installed app': 'Перезаписати встановлений додаток',
'Pack all': 'Запак.все',
'Pack compiled': 'Запак.компл',
'Pack all': 'Пакувати все',
'Pack compiled': 'Пакувати зкомпільоване',
'Pack custom': 'Пакувати вибране',
'pack plugin': 'запакувати втулку',
'PAM authenticated user, cannot change password here': 'Ввімкнена система ідентифікації користувачів PAM. Для зміни паролю скористайтесь командами вашої ОС ',
'password changed': 'пароль змінено',
@@ -322,13 +343,17 @@
'Query:': 'Запит:',
'RAM Cache Keys': 'Ключ ОЗП-кешу (RAM Cache)',
'Ram Cleared': "Кеш в пам'яті очищено",
'Rapid Search': 'Миттєвий пошук',
'record': 'запис',
'record does not exist': 'запису не існує',
'record id': 'Ід.запису',
'refresh': 'оновіть',
'reload': 'перевантажити',
'Reload routes': 'Перезавантажити маршрути',
'Remove compiled': 'Вилуч.компл',
'Removed Breakpoint on %s at line %s': 'Вилучено точку зупинки у %s в рядку %s',
'Replace': 'Замінити',
'Replace All': 'Замінити все',
'request': 'запит',
'requires python-git, but not installed': 'Для розгортання необхідний пакет python-git, але він не встановлений',
'resolve': "розв'язати",
@@ -349,6 +374,8 @@
'Running on %s': 'Запущено на %s',
'runonce': 'одноразово',
'Save': 'Зберегти',
'Save file:': 'Зберегти файл:',
'Save file: %s': 'Зберегти файл: %s',
'Save via Ajax': 'зберегти через Ajax',
'Saved file hash:': 'Хеш збереженого файлу:',
'search': 'пошук',
@@ -366,8 +393,10 @@
'some files could not be removed': 'деякі файли не можна вилучити',
'Sorry, could not find mercurial installed': 'Не вдалось виявити встановлену систему контролю версій Mercurial',
'Start a new app': 'Створюється новий додаток',
'Start searching': 'Розпочати пошук',
'Start wizard': 'Активувати майстра',
'state': 'стан',
'Static': 'Статичні',
'static': 'статичні',
'Static files': 'Статичні файли',
'Step': 'Крок',
@@ -376,6 +405,7 @@
'submit': 'застосувати',
'Submit': 'Застосувати',
'successful': 'успішно',
'switch to : db': 'перемкнути на : БД',
'table': 'таблиця',
'tags': 'мітки (tags)',
'Temporary': 'Тимчасово',
@@ -450,8 +480,10 @@
'Update:': 'Поновити:',
'Upgrade': 'Оновити',
'upgrade now': 'оновитись зараз',
'upgrade now to %s': 'оновити зараз до %s',
'upgrade_web2py': 'оновити web2py',
'upload': 'завантажити',
'Upload': 'Завантажити',
'Upload a package:': 'Завантажити пакет:',
'Upload and install packed application': 'Завантажити та встановити запакований додаток',
'upload file:': 'завантажити файл:',

View File

@@ -9,7 +9,8 @@ WEB2PY_VERSION_URL = WEB2PY_URL + '/examples/default/version'
# browser.
## Default editor (to change editor you need web2py.admin.editors.zip)
TEXT_EDITOR = 'codemirror' or 'ace' or 'edit_area' or 'amy'
## old editors like 'ace' or 'edit_area' or 'amy' are no longer supported
TEXT_EDITOR = 'codemirror'
## Editor Color scheme (only for ace)
TEXT_EDITOR_THEME = (

View File

@@ -8,6 +8,7 @@ from gluon.fileutils import read_file
# ## make sure administrator is on localhost or https
# ###########################################################
http_host = request.env.http_host.split(':')[0]
if request.env.web2py_runtime_gae:
@@ -49,7 +50,7 @@ def verify_password(password):
session.pam_user = None
if DEMO_MODE:
return True
elif not 'password' in _config:
elif not _config.get('password'):
return False
elif _config['password'].startswith('pam_user:'):
session.pam_user = _config['password'][9:].strip()
@@ -145,6 +146,10 @@ elif session.is_mobile == 'false':
else:
is_mobile = request.user_agent().is_mobile
if DEMO_MODE:
session.authorized = True
session.forget()
if request.controller == "webservices":
basic = request.env.http_authorization
if not basic or not basic[:6].lower() == 'basic ':

View File

@@ -2,5 +2,5 @@
theme = web2py
[editor]
theme = night
theme = web2py

View File

@@ -4,12 +4,12 @@
- [Submitting bug reports](#submitting-bug-reports-)
- [Contributing code](#contributing-code-)
## Getting help [^](#how-to-contribute)
## Getting help
Community discussion, questions, and informal bug reporting is done on the
[CodeMirror Google group](http://groups.google.com/group/codemirror).
## Submitting bug reports [^](#how-to-contribute)
## Submitting bug reports
The preferred way to report bugs is to use the
[GitHub issue tracker](http://github.com/marijnh/CodeMirror/issues). Before
@@ -45,7 +45,7 @@ should be asked on the
[jsbin.com](http://jsbin.com/ihunin/edit), enter it there, press save, and
include the resulting link in your bug report.
## Contributing code [^](#how-to-contribute)
## Contributing code
- Make sure you have a [GitHub Account](https://github.com/signup/free)
- Fork [CodeMirror](https://github.com/marijnh/CodeMirror/)

View File

@@ -1,4 +1,4 @@
Copyright (C) 2013 by Marijn Haverbeke <marijnh@gmail.com>
Copyright (C) 2013 by Marijn Haverbeke <marijnh@gmail.com> and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -17,7 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Please note that some subdirectories of the CodeMirror distribution
include their own LICENSE files, and are released under different
licences.

View File

@@ -17,7 +17,7 @@
CodeMirror.defineExtension("lineComment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = CodeMirror.innerMode(self.getMode(), self.getTokenAt(from).state).mode;
var self = this, mode = self.getModeAt(from);
var commentString = options.lineComment || mode.lineComment;
if (!commentString) {
if (options.blockCommentStart || mode.blockCommentStart) {
@@ -52,7 +52,7 @@
CodeMirror.defineExtension("blockComment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = CodeMirror.innerMode(self.getMode(), self.getTokenAt(from).state).mode;
var self = this, mode = self.getModeAt(from);
var startString = options.blockCommentStart || mode.blockCommentStart;
var endString = options.blockCommentEnd || mode.blockCommentEnd;
if (!startString || !endString) {
@@ -85,7 +85,7 @@
CodeMirror.defineExtension("uncomment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = CodeMirror.innerMode(self.getMode(), self.getTokenAt(from).state).mode;
var self = this, mode = self.getModeAt(from);
var end = Math.min(to.line, self.lastLine()), start = Math.min(from.line, end);
// Try finding line comments

View File

@@ -0,0 +1,6 @@
.CodeMirror-fullscreen {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
height: auto;
z-index: 9;
}

View File

@@ -0,0 +1,30 @@
(function() {
"use strict";
CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
if (old == CodeMirror.Init) old = false;
if (!old == !val) return;
if (val) setFullscreen(cm);
else setNormal(cm);
});
function setFullscreen(cm) {
var wrap = cm.getWrapperElement();
cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
width: wrap.style.width, height: wrap.style.height};
wrap.style.width = wrap.style.height = "";
wrap.className += " CodeMirror-fullscreen";
document.documentElement.style.overflow = "hidden";
cm.refresh();
}
function setNormal(cm) {
var wrap = cm.getWrapperElement();
wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
document.documentElement.style.overflow = "";
var info = cm.state.fullScreenRestore;
wrap.style.width = info.width; wrap.style.height = info.height;
window.scrollTo(info.scrollLeft, info.scrollTop);
cm.refresh();
}
})();

View File

@@ -54,7 +54,9 @@
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);
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

View File

@@ -27,9 +27,9 @@
if (val && (old == CodeMirror.Init || !old)) {
var map = {name: "autoCloseTags"};
if (typeof val != "object" || val.whenClosing)
map["'/'"] = function(cm) { return autoCloseTag(cm, '/'); };
map["'/'"] = function(cm) { return autoCloseSlash(cm); };
if (typeof val != "object" || val.whenOpening)
map["'>'"] = function(cm) { return autoCloseTag(cm, '>'); };
map["'>'"] = function(cm) { return autoCloseGT(cm); };
cm.addKeyMap(map);
} else if (!val && (old != CodeMirror.Init && old)) {
cm.removeKeyMap("autoCloseTags");
@@ -41,40 +41,41 @@
var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
"h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
function autoCloseTag(cm, ch) {
function autoCloseGT(cm) {
var pos = cm.getCursor(), tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (inner.mode.name != "xml") return CodeMirror.Pass;
if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass;
var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html";
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
if (ch == ">" && state.tagName) {
var tagName = state.tagName;
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
var lowerTagName = tagName.toLowerCase();
// Don't process the '>' at the end of an end-tag or self-closing tag
if (tok.type == "tag" && state.type == "closeTag" ||
tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1)
return CodeMirror.Pass;
var tagName = state.tagName;
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
var lowerTagName = tagName.toLowerCase();
// Don't process the '>' at the end of an end-tag or self-closing tag
if (tok.type == "tag" && state.type == "closeTag" ||
tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1)
return CodeMirror.Pass;
var doIndent = indentTags && indexOf(indentTags, lowerTagName) > -1;
var curPos = doIndent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1);
cm.replaceSelection(">" + (doIndent ? "\n\n" : "") + "</" + tagName + ">",
{head: curPos, anchor: curPos});
if (doIndent) {
cm.indentLine(pos.line + 1);
cm.indentLine(pos.line + 2);
}
return;
} else if (ch == "/" && tok.string == "<") {
var tagName = state.context && state.context.tagName;
if (tagName) cm.replaceSelection("/" + tagName + ">", "end");
return;
var doIndent = indentTags && indexOf(indentTags, lowerTagName) > -1;
var curPos = doIndent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1);
cm.replaceSelection(">" + (doIndent ? "\n\n" : "") + "</" + tagName + ">",
{head: curPos, anchor: curPos});
if (doIndent) {
cm.indentLine(pos.line + 1);
cm.indentLine(pos.line + 2);
}
return CodeMirror.Pass;
}
function autoCloseSlash(cm) {
var pos = cm.getCursor(), tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (tok.string.charAt(0) != "<" || inner.mode.name != "xml") return CodeMirror.Pass;
var tagName = state.context && state.context.tagName;
if (tagName) cm.replaceSelection("/" + tagName + ">", "end");
}
function indexOf(collection, elt) {

View File

@@ -1,44 +0,0 @@
(function() {
var modes = ["clike", "css", "javascript"];
for (var i = 0; i < modes.length; ++i)
CodeMirror.extendMode(modes[i], {blockCommentStart: "/*",
blockCommentEnd: "*/",
blockCommentContinue: " * "});
function continueComment(cm) {
var pos = cm.getCursor(), token = cm.getTokenAt(pos);
var mode = CodeMirror.innerMode(cm.getMode(), token.state).mode;
var space;
if (token.type == "comment" && mode.blockCommentStart) {
var end = token.string.indexOf(mode.blockCommentEnd);
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) {
// Comment ended, don't continue it
} else if (token.string.indexOf(mode.blockCommentStart) == 0) {
space = full.slice(0, token.start);
if (!/^\s*$/.test(space)) {
space = "";
for (var i = 0; i < token.start; ++i) space += " ";
}
} else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 &&
found + mode.blockCommentContinue.length > token.start &&
/^\s*$/.test(full.slice(0, found))) {
space = full.slice(0, found);
}
}
if (space != null)
cm.replaceSelection("\n" + space + mode.blockCommentContinue, "end");
else
return CodeMirror.Pass;
}
CodeMirror.defineOption("continueComments", null, function(cm, val, prev) {
if (prev && prev != CodeMirror.Init)
cm.removeKeyMap("continueComment");
var map = {name: "continueComment"};
map[typeof val == "string" ? val : "Enter"] = continueComment;
cm.addKeyMap(map);
});
})();

View File

@@ -1,10 +1,10 @@
CodeMirror.braceRangeFinder = function(cm, start) {
CodeMirror.registerHelper("fold", "brace", function(cm, start) {
var line = start.line, lineText = cm.getLine(line);
var startCh, tokenType;
function findOpening(openCh) {
for (var at = start.ch, pass = 0;;) {
var found = lineText.lastIndexOf(openCh, at - 1);
var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);
if (found == -1) {
if (pass == 1) break;
pass = 1;
@@ -12,7 +12,7 @@ CodeMirror.braceRangeFinder = function(cm, start) {
continue;
}
if (pass == 1 && found < start.ch) break;
tokenType = cm.getTokenAt(CodeMirror.Pos(line, found + 1)).type;
tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
if (!/^(comment|string)/.test(tokenType)) return found + 1;
at = found - 1;
}
@@ -34,7 +34,7 @@ CodeMirror.braceRangeFinder = function(cm, start) {
if (nextClose < 0) nextClose = text.length;
pos = Math.min(nextOpen, nextClose);
if (pos == text.length) break;
if (cm.getTokenAt(CodeMirror.Pos(i, pos + 1)).type == tokenType) {
if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {
if (pos == nextOpen) ++count;
else if (!--count) { end = i; endCh = pos; break outer; }
}
@@ -44,9 +44,10 @@ CodeMirror.braceRangeFinder = function(cm, start) {
if (end == null || line == end && endCh == startCh) return;
return {from: CodeMirror.Pos(line, startCh),
to: CodeMirror.Pos(end, endCh)};
};
});
CodeMirror.braceRangeFinder = CodeMirror.fold.brace; // deprecated
CodeMirror.importRangeFinder = function(cm, start) {
CodeMirror.registerHelper("fold", "import", function(cm, start) {
function hasImport(line) {
if (line < cm.firstLine() || line > cm.lastLine()) return null;
var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
@@ -68,9 +69,10 @@ CodeMirror.importRangeFinder = function(cm, start) {
end = next.end;
}
return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end};
};
});
CodeMirror.importRangeFinder = CodeMirror.fold["import"]; // deprecated
CodeMirror.includeRangeFinder = function(cm, start) {
CodeMirror.registerHelper("fold", "include", function(cm, start) {
function hasInclude(line) {
if (line < cm.firstLine() || line > cm.lastLine()) return null;
var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
@@ -87,4 +89,5 @@ CodeMirror.includeRangeFinder = function(cm, start) {
}
return {from: CodeMirror.Pos(start, has + 1),
to: cm.clipPos(CodeMirror.Pos(end))};
};
});
CodeMirror.includeRangeFinder = CodeMirror.fold.include; // deprecated

View File

@@ -2,7 +2,8 @@
"use strict";
function doFold(cm, pos, options) {
var finder = options.call ? options : (options && options.rangeFinder);
var finder = options && (options.call ? options : options.rangeFinder);
if (!finder) finder = cm.getHelper(pos, "fold");
if (!finder) return;
if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
var minSize = options && options.minFoldSize || 0;
@@ -29,12 +30,16 @@
if (!range || range.cleared) return;
var myWidget = makeWidget(options);
CodeMirror.on(myWidget, "mousedown", function() {myRange.clear();});
CodeMirror.on(myWidget, "mousedown", function() { myRange.clear(); });
var myRange = cm.markText(range.from, range.to, {
replacedWith: myWidget,
clearOnEnter: true,
__isFold: true
});
myRange.on("clear", function(from, to) {
CodeMirror.signal(cm, "unfold", cm, from, to);
});
CodeMirror.signal(cm, "fold", cm, range.from, range.to);
}
function makeWidget(options) {
@@ -56,7 +61,7 @@
// New-style interface
CodeMirror.defineExtension("foldCode", function(pos, options) { doFold(this, pos, options); });
CodeMirror.combineRangeFinders = function() {
CodeMirror.registerHelper("fold", "combine", function() {
var funcs = Array.prototype.slice.call(arguments, 0);
return function(cm, start) {
for (var i = 0; i < funcs.length; ++i) {
@@ -64,5 +69,5 @@
if (found) return found;
}
};
};
});
})();

View File

@@ -1,4 +1,4 @@
CodeMirror.indentRangeFinder = function(cm, start) {
CodeMirror.registerHelper("fold", "indent", function(cm, start) {
var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line);
var myIndent = CodeMirror.countColumn(firstLine, null, tabSize);
for (var i = start.line + 1, end = cm.lineCount(); i < end; ++i) {
@@ -8,4 +8,5 @@ CodeMirror.indentRangeFinder = function(cm, start) {
return {from: CodeMirror.Pos(start.line, firstLine.length),
to: CodeMirror.Pos(i, curLine.length)};
}
};
});
CodeMirror.indentRangeFinder = CodeMirror.fold.indent; // deprecated

View File

@@ -2,14 +2,17 @@
"use strict";
var Pos = CodeMirror.Pos;
function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }
var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");
function Iter(cm, line, ch) {
function Iter(cm, line, ch, range) {
this.line = line; this.ch = ch;
this.cm = cm; this.text = cm.getLine(line);
this.min = range ? range.from : cm.firstLine();
this.max = range ? range.to - 1 : cm.lastLine();
}
function tagAt(iter, ch) {
@@ -18,13 +21,13 @@
}
function nextLine(iter) {
if (iter.line >= iter.cm.lastLine()) return;
if (iter.line >= iter.max) return;
iter.ch = 0;
iter.text = iter.cm.getLine(++iter.line);
return true;
}
function prevLine(iter) {
if (iter.line <= iter.cm.firstLine()) return;
if (iter.line <= iter.min) return;
iter.text = iter.cm.getLine(--iter.line);
iter.ch = iter.text.length;
return true;
@@ -43,7 +46,7 @@
}
function toTagStart(iter) {
for (;;) {
var lt = iter.text.lastIndexOf("<", iter.ch - 1);
var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1;
if (lt == -1) { if (prevLine(iter)) continue; else return; }
if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }
xmlTagStart.lastIndex = lt;
@@ -65,7 +68,7 @@
}
function toPrevTag(iter) {
for (;;) {
var gt = iter.text.lastIndexOf(">", iter.ch - 1);
var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1;
if (gt == -1) { if (prevLine(iter)) continue; else return; }
if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }
var lastSlash = iter.text.lastIndexOf("/", gt);
@@ -121,7 +124,7 @@
}
}
CodeMirror.tagRangeFinder = function(cm, start) {
CodeMirror.registerHelper("fold", "xml", function(cm, start) {
var iter = new Iter(cm, start.line, 0);
for (;;) {
var openTag = toNextTag(iter), end;
@@ -132,27 +135,31 @@
return close && {from: start, to: close.from};
}
}
};
});
CodeMirror.tagRangeFinder = CodeMirror.fold.xml; // deprecated
CodeMirror.findMatchingTag = function(cm, pos) {
var iter = new Iter(cm, pos.line, pos.ch);
var end = toTagEnd(iter), start = toTagStart(iter);
if (!end || end == "selfClose" || !start) return;
CodeMirror.findMatchingTag = function(cm, pos, range) {
var iter = new Iter(cm, pos.line, pos.ch, range);
if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
var start = end && toTagStart(iter);
if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return;
var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};
if (start[1]) { // closing tag
return findMatchingOpen(iter, start[2]);
return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};
} else { // opening tag
toTagEnd(iter);
return findMatchingClose(iter, start[2]);
iter = new Iter(cm, to.line, to.ch, range);
return {open: here, close: findMatchingClose(iter, start[2]), at: "open"};
}
};
CodeMirror.findEnclosingTag = function(cm, pos) {
var iter = new Iter(cm, pos.line, pos.ch);
CodeMirror.findEnclosingTag = function(cm, pos, range) {
var iter = new Iter(cm, pos.line, pos.ch, range);
for (;;) {
var open = findMatchingOpen(iter);
if (!open) break;
var forward = new Iter(cm, pos.line, pos.ch);
var forward = new Iter(cm, pos.line, pos.ch, range);
var close = findMatchingClose(forward, open.tag);
if (close) return {open: open, close: close};
}

View File

@@ -327,9 +327,11 @@
populate(data[tag]);
CodeMirror.htmlSchema = data;
CodeMirror.htmlHint = function(cm, options) {
function htmlHint(cm, options) {
var local = {schemaInfo: data};
if (options) for (var opt in options) local[opt] = options[opt];
return CodeMirror.xmlHint(cm, local);
};
return CodeMirror.hint.xml(cm, local);
}
CodeMirror.htmlHint = htmlHint; // deprecated
CodeMirror.registerHelper("hint", "html", htmlHint);
})();

View File

@@ -56,11 +56,13 @@
to: Pos(cur.line, token.end)};
}
CodeMirror.javascriptHint = function(editor, options) {
function javascriptHint(editor, options) {
return scriptHint(editor, javascriptKeywords,
function (e, cur) {return e.getTokenAt(cur);},
options);
};
CodeMirror.javascriptHint = javascriptHint; // deprecated
CodeMirror.registerHelper("hint", "javascript", javascriptHint);
function getCoffeeScriptToken(editor, cur) {
// This getToken, it is for coffeescript, imitates the behavior of
@@ -80,9 +82,11 @@
return token;
}
CodeMirror.coffeescriptHint = function(editor, options) {
function coffeescriptHint(editor, options) {
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
};
}
CodeMirror.coffeescriptHint = coffeescriptHint; // deprecated
CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
"toUpperCase toLowerCase split concat match replace search").split(" ");

View File

@@ -1,4 +1,6 @@
(function () {
"use strict";
function forEach(arr, f) {
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
}
@@ -41,9 +43,11 @@
to: CodeMirror.Pos(cur.line, token.end)};
}
CodeMirror.pigHint = function(editor) {
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 "

View File

@@ -41,9 +41,11 @@
to: CodeMirror.Pos(cur.line, token.end)};
}
CodeMirror.pythonHint = function(editor) {
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";

View File

@@ -4,6 +4,8 @@
CodeMirror.showHint = function(cm, getHints, options) {
// We want a single cursor position.
if (cm.somethingSelected()) return;
if (getHints == null) getHints = cm.getHelper(cm.getCursor(), "hint");
if (getHints == null) return;
if (cm.state.completionActive) cm.state.completionActive.close();
@@ -25,10 +27,10 @@
Completion.prototype = {
close: function() {
if (!this.active()) return;
this.cm.state.completionActive = null;
if (this.widget) this.widget.close();
if (this.onClose) this.onClose();
this.cm.state.completionActive = null;
CodeMirror.signal(this.cm, "endCompletion", this.cm);
},
@@ -65,24 +67,21 @@
finished = true;
completion.close();
completion.cm.off("cursorActivity", activity);
CodeMirror.signal(data, "close");
}
function isDone() {
if (finished) return true;
if (!completion.widget) { done(); return true; }
if (data) CodeMirror.signal(data, "close");
}
function update() {
if (isDone()) return;
if (finished) return;
CodeMirror.signal(data, "update");
if (completion.options.async)
completion.getHints(completion.cm, finishUpdate, completion.options);
else
finishUpdate(completion.getHints(completion.cm, completion.options));
}
function finishUpdate(data) {
if (isDone()) return;
function finishUpdate(data_) {
data = data_;
if (finished) return;
if (!data || !data.list.length) return done();
completion.widget.close();
completion.widget = new Widget(completion, data);
}
@@ -91,10 +90,12 @@
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))))
(pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {
completion.close();
else
} else {
debounce = setTimeout(update, 170);
if (completion.widget) completion.widget.close();
}
}
this.cm.on("cursorActivity", activity);
this.onClose = done;
@@ -110,10 +111,10 @@
var baseMap = {
Up: function() {handle.moveFocus(-1);},
Down: function() {handle.moveFocus(1);},
PageUp: function() {handle.moveFocus(-handle.menuSize());},
PageDown: function() {handle.moveFocus(handle.menuSize());},
PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
Home: function() {handle.setFocus(0);},
End: function() {handle.setFocus(handle.length);},
End: function() {handle.setFocus(handle.length - 1);},
Enter: handle.pick,
Tab: handle.pick,
Esc: handle.close
@@ -166,6 +167,7 @@
// 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 winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
(options.container || document.body).appendChild(hints);
var box = hints.getBoundingClientRect();
var overlapX = box.right - winW, overlapY = box.bottom - winH;
if (overlapX > 0) {
@@ -186,10 +188,9 @@
}
hints.style.top = (top = pos.bottom - overlapY) + "px";
}
(options.container || document.body).appendChild(hints);
cm.addKeyMap(this.keyMap = buildKeyMap(options, {
moveFocus: function(n) { widget.changeActive(widget.selectedHint + n); },
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
setFocus: function(n) { widget.changeActive(n); },
menuSize: function() { return widget.screenAmount(); },
length: completions.length,
@@ -249,8 +250,11 @@
this.completion.pick(this.data, this.selectedHint);
},
changeActive: function(i) {
i = Math.max(0, Math.min(i, this.data.list.length - 1));
changeActive: function(i, avoidWrap) {
if (i >= this.data.list.length)
i = avoidWrap ? this.data.list.length - 1 : 0;
else if (i < 0)
i = avoidWrap ? 0 : this.data.list.length - 1;
if (this.selectedHint == i) return;
var node = this.hints.childNodes[this.selectedHint];
node.className = node.className.replace(" CodeMirror-hint-active", "");

View File

@@ -3,7 +3,7 @@
var Pos = CodeMirror.Pos;
CodeMirror.xmlHint = function(cm, options) {
function getHints(cm, options) {
var tags = options && options.schemaInfo;
var quote = (options && options.quoteChar) || '"';
if (!tags) return;
@@ -61,5 +61,8 @@
from: replaceToken ? Pos(cur.line, token.start) : cur,
to: replaceToken ? Pos(cur.line, token.end) : cur
};
};
}
CodeMirror.xmlHint = getHints; // deprecated
CodeMirror.registerHelper("hint", "xml", getHints);
})();

View File

@@ -1,6 +1,8 @@
// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js
CodeMirror.coffeeValidator = function(text) {
// declare global: coffeelint
CodeMirror.registerHelper("lint", "coffeescript", function(text) {
var found = [];
var parseError = function(err) {
var loc = err.lineNumber;
@@ -21,4 +23,5 @@ CodeMirror.coffeeValidator = function(text) {
message: e.message});
}
return found;
};
});
CodeMirror.coffeeValidator = CodeMirror.lint.coffeescript; // deprecated

View File

@@ -1,4 +1,6 @@
(function() {
"use strict";
// declare global: JSHINT
var bogus = [ "Dangerous comment" ];
@@ -9,18 +11,15 @@
"Unmatched ", " and instead saw", " is not defined",
"Unclosed string", "Stopping, unable to continue" ];
function validator(options, text) {
function validator(text, options) {
JSHINT(text, options);
var errors = JSHINT.data().errors, result = [];
if (errors) parseErrors(errors, result);
return result;
}
CodeMirror.javascriptValidatorWithOptions = function(options) {
return function(text) { return validator(options, text); };
};
CodeMirror.javascriptValidator = CodeMirror.javascriptValidatorWithOptions(null);
CodeMirror.registerHelper("lint", "javascript", validator);
CodeMirror.javascriptValidator = CodeMirror.lint.javascript; // deprecated
function cleanup(error) {
// All problems are warnings by default

View File

@@ -1,6 +1,8 @@
// Depends on jsonlint.js from https://github.com/zaach/jsonlint
CodeMirror.jsonValidator = function(text) {
// declare global: jsonlint
CodeMirror.registerHelper("lint", "json", function(text) {
var found = [];
jsonlint.parseError = function(str, hash) {
var loc = hash.loc;
@@ -11,4 +13,5 @@ CodeMirror.jsonValidator = function(text) {
try { jsonlint.parse(text); }
catch(e) {}
return found;
};
});
CodeMirror.jsonValidator = CodeMirror.lint.json; // deprecated

View File

@@ -57,40 +57,16 @@
}
.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error {
background-image: url("data:image/gif;base64,R0lGODlhEAAQANUAAPVvcvWHiPVucvRuc+ttcfV6f91KVN5LU99PV/FZY/JhaM4oN84pONE4Rd1ATfJLWutVYPRgbdxpcsgWKMgZKs4lNfE/UvE/U+artcpdSc5uXveimslHPuBhW/eJhfV5efaCgO2CgP+/v+PExP///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACUALAAAAAAQABAAAAZ+wJJwSCwaScgkySgkjTQZTkYzWhadnE5oE+pwqkSshwQqkzxfa4kkQXxEpA9J9EFI1KQGQQBAigYCBA14ExEWF0gXihETeA0QD3AkD5QQg0NsDnAJmwkOd5gYFSQKpXAFDBhqaxgLBwQBBAapq00YEg0UDRKqTGtKSL7Cw8JBADs=");
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning {
background-image: url("data:image/gif;base64,R0lGODlhEAAQANUAAP7bc//egf/ij/7ijv/jl/7kl//mnv7lnv/uwf7CTP7DTf7DT/7IW//Na/7Na//NbP7QdP/dmbltAIJNAF03AMSAJMSCLKqASa2DS6uBSquCSrGHTq6ETbCHT7WKUrKIUcCVXL+UXMOYX8GWXsSZYMiib6+ETbOIUcOXX86uhd3Muf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACsALAAAAAAQABAAAAZowJVwSCwaj0ihikRSJYcoBEL0XKlGkcjImQQhJBREKFnyICoThKeE/AAW6AXgdPyUAgrLJBEo0YsbAQyDhAEdRRwDDw8OaA4NDQImRBgFEJdglxAEGEQZKQcHBqOkKRpFF6mqq1WtrUEAOw==");
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-multiple {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJEAQvB2JVdrAAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAD1JREFUCNdtjkESADAEAzemf69f66HMqGlOIhYiFRFRtSQBWAY7mzx+EDTL6sSgb1jTk7Q87rxyqe37fXsAa78gLyZnRgEAAAAASUVORK5CYII=");
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
background-position: right bottom;
width: 100%; height: 100%;
}
/* Styles for the overview ruler
.annotationOverview {
cursor: pointer;
border-radius: 2px;
left: 2px;
width: 8px;
}
.annotationOverview.error {
background-color: lightcoral;
border: 1px solid darkred;
}
.annotationOverview.warning {
background-color: Gold;
border: 1px solid black;
}
.annotationHTML.overlay {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJEAQvB2JVdrAAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAD1JREFUCNdtjkESADAEAzemf69f66HMqGlOIhYiFRFRtSQBWAY7mzx+EDTL6sSgb1jTk7Q87rxyqe37fXsAa78gLyZnRgEAAAAASUVORK5CYII=");
background-position: right bottom;
position: relative;
top: -16px;
}
*/

View File

@@ -1,4 +1,5 @@
CodeMirror.validate = (function() {
(function() {
"use strict";
var GUTTER_ID = "CodeMirror-lint-markers";
var SEVERITIES = /^(?:error|warning)$/;
@@ -52,9 +53,11 @@ CodeMirror.validate = (function() {
this.onMouseOver = function(e) { onMouseOver(cm, e); };
}
function parseOptions(options) {
function parseOptions(cm, options) {
if (options instanceof Function) return {getAnnotations: options};
else if (!options || !options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)");
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;
}
@@ -109,7 +112,7 @@ CodeMirror.validate = (function() {
if (options.async)
options.getAnnotations(cm, updateLinting, options);
else
updateLinting(cm, options.getAnnotations(cm.getValue()));
updateLinting(cm, options.getAnnotations(cm.getValue(), options));
}
function updateLinting(cm, annotationsNotSorted) {
@@ -175,7 +178,7 @@ CodeMirror.validate = (function() {
}
}
CodeMirror.defineOption("lintWith", false, function(cm, val, old) {
function optionHandler(cm, val, old) {
if (old && old != CodeMirror.Init) {
clearMarks(cm);
cm.off("change", onChange);
@@ -186,12 +189,15 @@ CodeMirror.validate = (function() {
if (val) {
var gutters = cm.getOption("gutters"), hasLintGutter = false;
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
var state = cm.state.lint = new LintState(cm, parseOptions(val), hasLintGutter);
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
cm.on("change", onChange);
if (state.options.tooltips != false)
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
startLinting(cm);
}
});
}
CodeMirror.defineOption("lintWith", false, optionHandler); // deprecated
CodeMirror.defineOption("lint", false, optionHandler); // deprecated
})();

View File

@@ -1,24 +1,34 @@
.CodeMirror-diff {
.CodeMirror-merge {
position: relative;
border: 1px solid #ddd;
white-space: pre;
}
.CodeMirror-diff, .CodeMirror-diff .CodeMirror {
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
height: 350px;
}
.CodeMirror-diff-2pane .CodeMirror-diff-pane { width: 47%; }
.CodeMirror-diff-2pane .CodeMirror-diff-gap { width: 6%; }
.CodeMirror-diff-3pane .CodeMirror-diff-pane { width: 31%; }
.CodeMirror-diff-3pane .CodeMirror-diff-gap { width: 3.5%; }
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; }
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; }
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
.CodeMirror-diff-pane {
float: left;
.CodeMirror-merge-pane {
display: inline-block;
white-space: normal;
vertical-align: top;
}
.CodeMirror-merge-pane-rightmost {
position: absolute;
right: 0px;
z-index: 1;
}
.CodeMirror-diff-gap {
float: left;
.CodeMirror-merge-gap {
z-index: 2;
display: inline-block;
height: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
border-left: 1px solid #ddd;
@@ -27,11 +37,11 @@
background: #f8f8f8;
}
.CodeMirror-diff-scrolllock-wrap {
.CodeMirror-merge-scrolllock-wrap {
position: absolute;
bottom: 0; left: 50%;
}
.CodeMirror-diff-scrolllock {
.CodeMirror-merge-scrolllock {
position: relative;
left: -50%;
cursor: pointer;
@@ -39,44 +49,44 @@
line-height: 1;
}
.CodeMirror-diff-copybuttons-left, .CodeMirror-diff-copybuttons-right {
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
position: absolute;
left: 0; top: 0;
right: 0; bottom: 0;
line-height: 1;
}
.CodeMirror-diff-copy {
.CodeMirror-merge-copy {
position: absolute;
cursor: pointer;
color: #44c;
}
.CodeMirror-diff-copybuttons-left .CodeMirror-diff-copy { left: 2px; }
.CodeMirror-diff-copybuttons-right .CodeMirror-diff-copy { right: 2px; }
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
.CodeMirror-diff-r-inserted, .CodeMirror-diff-l-inserted {
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-diff-r-deleted, .CodeMirror-diff-l-deleted {
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-diff-r-chunk { background: #ffffe0; }
.CodeMirror-diff-r-chunk-start { border-top: 1px solid #ee8; }
.CodeMirror-diff-r-chunk-end { border-bottom: 1px solid #ee8; }
.CodeMirror-diff-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }
.CodeMirror-merge-r-chunk { background: #ffffe0; }
.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; }
.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; }
.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }
.CodeMirror-diff-l-chunk { background: #eef; }
.CodeMirror-diff-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-diff-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-diff-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
.CodeMirror-merge-l-chunk { background: #eef; }
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
.CodeMirror-diff-l-chunk.CodeMirror-diff-r-chunk { background: #dfd; }
.CodeMirror-diff-l-chunk-start.CodeMirror-diff-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-diff-l-chunk-end.CodeMirror-diff-r-chunk-end { border-bottom: 1px solid #4e4; }
.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-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }

View File

@@ -1,5 +1,6 @@
(function() {
"use strict";
// declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL
var Pos = CodeMirror.Pos;
var svgNS = "http://www.w3.org/2000/svg";
@@ -8,18 +9,18 @@
this.mv = mv;
this.type = type;
this.classes = type == "left"
? {chunk: "CodeMirror-diff-l-chunk",
start: "CodeMirror-diff-l-chunk-start",
end: "CodeMirror-diff-l-chunk-end",
insert: "CodeMirror-diff-l-inserted",
del: "CodeMirror-diff-l-deleted",
connect: "CodeMirror-diff-l-connect"}
: {chunk: "CodeMirror-diff-r-chunk",
start: "CodeMirror-diff-r-chunk-start",
end: "CodeMirror-diff-r-chunk-end",
insert: "CodeMirror-diff-r-inserted",
del: "CodeMirror-diff-r-deleted",
connect: "CodeMirror-diff-r-connect"};
? {chunk: "CodeMirror-merge-l-chunk",
start: "CodeMirror-merge-l-chunk-start",
end: "CodeMirror-merge-l-chunk-end",
insert: "CodeMirror-merge-l-inserted",
del: "CodeMirror-merge-l-deleted",
connect: "CodeMirror-merge-l-connect"}
: {chunk: "CodeMirror-merge-r-chunk",
start: "CodeMirror-merge-r-chunk-start",
end: "CodeMirror-merge-r-chunk-end",
insert: "CodeMirror-merge-r-inserted",
del: "CodeMirror-merge-r-deleted",
connect: "CodeMirror-merge-r-connect"};
}
DiffView.prototype = {
@@ -31,9 +32,17 @@
this.diff = getDiff(orig, options.value);
this.diffOutOfDate = false;
this.showDifferences = options.showDifferences !== false;
this.forceUpdate = registerUpdate(this);
setScrollLock(this, true, false);
registerScroll(this);
},
setShowDifferences: function(val) {
val = val !== false;
if (val != this.showDifferences) {
this.showDifferences = val;
this.forceUpdate("full");
}
}
};
@@ -41,26 +50,38 @@
var edit = {from: 0, to: 0, marked: []};
var orig = {from: 0, to: 0, marked: []};
var debounceChange;
function update() {
function update(mode) {
if (mode == "full") {
if (dv.svg) clear(dv.svg);
clear(dv.copyButtons);
clearMarks(dv.edit, edit.marked, dv.classes);
clearMarks(dv.orig, orig.marked, dv.classes);
edit.from = edit.to = orig.from = orig.to = 0;
}
if (dv.diffOutOfDate) {
dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
dv.diffOutOfDate = false;
CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
}
if (dv.showDifferences) {
updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
}
updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
drawConnectors(dv);
}
function set(slow) {
clearTimeout(debounceChange);
debounceChange = setTimeout(update, slow == true ? 250 : 100);
}
dv.edit.on("change", function() {
function change() {
if (!dv.diffOutOfDate) {
dv.diffOutOfDate = true;
edit.from = edit.to = orig.from = orig.to = 0;
}
set(true);
});
}
dv.edit.on("change", change);
dv.orig.on("change", change);
dv.edit.on("viewportChange", set);
dv.orig.on("viewportChange", set);
update();
@@ -93,7 +114,21 @@
var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig);
var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit);
var ratio = (midY - off.top) / (off.bot - off.top);
other.scrollTo(null, (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top));
var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top);
var botDist, mix;
// Some careful tweaking to make sure no space is left out of view
// when scrolling to top or bottom.
if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) {
targetPos = targetPos * mix + sInfo.top * (1 - mix);
} else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) {
var otherInfo = other.getScrollInfo();
var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos;
if (botDistOther > botDist && (mix = botDist / halfScreen) < 1)
targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix);
}
other.scrollTo(sInfo.left, targetPos);
other.state.scrollSetAt = now;
other.state.scrollSetBy = dv;
return true;
@@ -197,6 +232,8 @@
// Updating the gap between editor and original
function drawConnectors(dv) {
if (!dv.showDifferences) return;
if (dv.svg) {
clear(dv.svg);
var w = dv.gap.offsetWidth;
@@ -208,8 +245,8 @@
var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport();
var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top;
iterateChunks(dv.diff, function(topOrig, botOrig, topEdit, botEdit) {
if (topEdit >= vpEdit.to || botEdit < vpEdit.from ||
topOrig >= vpOrig.to || botOrig < vpOrig.from)
if (topEdit > vpEdit.to || botEdit < vpEdit.from ||
topOrig > vpOrig.to || botOrig < vpOrig.from)
return;
var topLpx = dv.orig.heightAtLine(topOrig, "local") - sTopOrig, top = topLpx;
if (dv.svg) {
@@ -225,7 +262,7 @@
"class", dv.classes.connect);
}
var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc",
"CodeMirror-diff-copy"));
"CodeMirror-merge-copy"));
copy.title = "Revert chunk";
copy.chunk = {topEdit: topEdit, botEdit: botEdit, topOrig: topOrig, botOrig: botOrig};
copy.style.top = top + "px";
@@ -250,23 +287,25 @@
if (hasLeft) {
left = this.left = new DiffView(this, "left");
var leftPane = elt("div", null, "CodeMirror-diff-pane");
var leftPane = elt("div", null, "CodeMirror-merge-pane");
wrap.push(leftPane);
wrap.push(buildGap(left));
}
var editPane = elt("div", null, "CodeMirror-diff-pane");
var editPane = elt("div", null, "CodeMirror-merge-pane");
wrap.push(editPane);
if (hasRight) {
right = this.right = new DiffView(this, "right");
wrap.push(buildGap(right));
var rightPane = elt("div", null, "CodeMirror-diff-pane");
var rightPane = elt("div", null, "CodeMirror-merge-pane");
wrap.push(rightPane);
}
(hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost";
wrap.push(elt("div", null, null, "height: 0; clear: both;"));
var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-diff CodeMirror-diff-" + panes + "pane"));
var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane"));
this.edit = CodeMirror(editPane, copyObj(options));
if (left) left.init(leftPane, origLeft, options);
@@ -284,11 +323,11 @@
};
function buildGap(dv) {
var lock = dv.lockButton = elt("div", null, "CodeMirror-diff-scrolllock");
var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock");
lock.title = "Toggle locked scrolling";
var lockWrap = elt("div", [lock], "CodeMirror-diff-scrolllock-wrap");
var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap");
CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); });
dv.copyButtons = elt("div", null, "CodeMirror-diff-copybuttons-" + dv.type);
dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type);
CodeMirror.on(dv.copyButtons, "click", function(e) {
var node = e.target || e.srcElement;
if (node.chunk) copyChunk(dv, node.chunk);
@@ -299,14 +338,18 @@
dv.svg = svg;
if (svg) gapElts.push(svg);
return dv.gap = elt("div", gapElts, "CodeMirror-diff-gap");
return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap");
}
MergeView.prototype = {
constuctor: MergeView,
editor: function() { return this.edit; },
rightOriginal: function() { return this.right && this.right.orig; },
leftOriginal: function() { return this.left && this.left.orig; }
leftOriginal: function() { return this.left && this.left.orig; },
setShowDifferences: function(val) {
if (this.right) this.right.setShowDifferences(val);
if (this.left) this.left.setShowDifferences(val);
}
};
// Operations on diffs

View File

@@ -2,6 +2,9 @@
window.CodeMirror = {};
(function() {
"use strict";
function splitLines(string){ return string.split(/\r?\n|\r/); };
function StringStream(string) {
@@ -43,12 +46,14 @@ StringStream.prototype = {
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
@@ -123,8 +128,9 @@ CodeMirror.runMode = function (string, modespec, callback, options) {
var stream = new CodeMirror.StringStream(lines[i]);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
})();

View File

@@ -49,7 +49,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
var stream = new CodeMirror.StringStream(lines[i]);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}

View File

@@ -41,12 +41,14 @@ StringStream.prototype = {
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
@@ -94,7 +96,7 @@ exports.runMode = function(string, modespec, callback) {
var stream = new exports.StringStream(lines[i]);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}

View File

@@ -15,15 +15,18 @@
(function() {
var DEFAULT_MIN_CHARS = 2;
var DEFAULT_TOKEN_STYLE = "matchhighlight";
var DEFAULT_DELAY = 100;
function State(options) {
if (typeof options == "object") {
this.minChars = options.minChars;
this.style = options.style;
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;
}
@@ -45,7 +48,7 @@
function cursorActivity(cm) {
var state = cm.state.matchHighlighter;
clearTimeout(state.timeout);
state.timeout = setTimeout(function() {highlightMatches(cm);}, 100);
state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay);
}
function highlightMatches(cm) {
@@ -55,11 +58,13 @@
cm.removeOverlay(state.overlay);
state.overlay = null;
}
if (!cm.somethingSelected() && state.showToken) {
var tok = cm.getTokenAt(cm.getCursor()).string;
if (/\w/.test(tok))
cm.addOverlay(state.overlay = makeOverlay(tok, true, state.style));
var re = state.showToken === true ? /[\w$]/ : state.showToken;
var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
while (start && re.test(line.charAt(start - 1))) --start;
while (end < line.length && re.test(line.charAt(end))) ++end;
if (start < end)
cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style));
return;
}
if (cm.getCursor("head").line != cm.getCursor("anchor").line) return;
@@ -69,15 +74,15 @@
});
}
function boundariesAround(stream) {
return (stream.start || /.\b./.test(stream.string.slice(stream.start - 1, stream.start + 1))) &&
(stream.pos == stream.string.length || /.\b./.test(stream.string.slice(stream.pos - 1, stream.pos + 1)));
function boundariesAround(stream, re) {
return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) &&
(stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
}
function makeOverlay(query, wordBoundaries, style) {
function makeOverlay(query, hasBoundary, style) {
return {token: function(stream) {
if (stream.match(query) &&
(!wordBoundaries || boundariesAround(stream)))
(!hasBoundary || boundariesAround(stream, hasBoundary)))
return style;
stream.next();
stream.skipTo(query.charAt(0)) || stream.skipToEnd();

View File

@@ -69,8 +69,8 @@
this.matches = function(reverse, pos) {
var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln));
var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match));
if (reverse ? offsetA >= pos.ch || offsetA != match.length
: offsetA <= pos.ch || offsetA != line.length - match.length)
if (reverse ? offsetA > pos.ch || offsetA != match.length
: offsetA < pos.ch || offsetA != line.length - match.length)
return;
for (;;) {
if (reverse ? !ln : ln == doc.lineCount() - 1) return;

View File

@@ -29,7 +29,7 @@
}
function updateActiveLine(cm) {
var line = cm.getLineHandle(cm.getCursor().line);
var line = cm.getLineHandleVisualStart(cm.getCursor().line);
if (cm.state.activeLine == line) return;
clearActiveLine(cm);
cm.addLineClass(line, "wrap", WRAP_CLASS);

View File

@@ -1,11 +1,12 @@
#!/usr/bin/env node
var lint = require("../test/lint/lint");
var lint = require("../test/lint/lint"),
path = require("path");
if (process.argv.length > 2) {
lint.checkDir(process.argv[2]);
} else {
process.chdir(__dirname.slice(0, __dirname.lastIndexOf("/")));
process.chdir(path.resolve(__dirname, ".."));
lint.checkDir("lib");
lint.checkDir("mode");
lint.checkDir("addon");

View File

@@ -353,7 +353,7 @@
},
"Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": repeated("undo"), "K": "close",
"Delete": function(cm) { kill(cm, cm.getCursor(), sentenceEnd(cm, 1), true); },
"Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
auto: "emacs", nofallthrough: true, disableInput: true
};

View File

@@ -40,6 +40,10 @@
* TODO: Implement the remaining special marks. They have more complex
* behavior.
*
* Events:
* 'vim-mode-change' - raised on the editor anytime the current mode changes,
* Event object: {mode: "visual", subMode: "linewise"}
*
* Code structure:
* 1. Default keymap
* 2. Variable declarations and short basic helpers
@@ -206,8 +210,7 @@
// Operators
{ keys: ['d'], type: 'operator', operator: 'delete' },
{ keys: ['y'], type: 'operator', operator: 'yank' },
{ keys: ['c'], type: 'operator', operator: 'change',
operatorArgs: { enterInsertMode: true } },
{ keys: ['c'], type: 'operator', operator: 'change' },
{ keys: ['>'], type: 'operator', operator: 'indent',
operatorArgs: { indentRight: true }},
{ keys: ['<'], type: 'operator', operator: 'indent',
@@ -231,10 +234,11 @@
motion: 'moveToEol', motionArgs: { inclusive: true },
operatorMotionArgs: { visualLine: true }},
{ keys: ['C'], type: 'operatorMotion',
operator: 'change', operatorArgs: { enterInsertMode: true },
operator: 'change',
motion: 'moveToEol', motionArgs: { inclusive: true },
operatorMotionArgs: { visualLine: true }},
{ keys: ['~'], type: 'operatorMotion', operator: 'swapcase',
{ keys: ['~'], type: 'operatorMotion',
operator: 'swapcase', operatorArgs: { shouldMoveCursor: true },
motion: 'moveByCharacters', motionArgs: { forward: true }},
// Actions
{ keys: ['<C-i>'], type: 'action', action: 'jumpListWalk',
@@ -315,6 +319,28 @@
];
var Vim = function() {
CodeMirror.defineOption('vimMode', false, function(cm, val) {
if (val) {
cm.setOption('keyMap', 'vim');
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
cm.on('beforeSelectionChange', beforeSelectionChange);
maybeInitVimState(cm);
} else if (cm.state.vim) {
cm.setOption('keyMap', 'default');
cm.off('beforeSelectionChange', beforeSelectionChange);
cm.state.vim = null;
}
});
function beforeSelectionChange(cm, cur) {
var vim = cm.state.vim;
if (vim.insertMode || vim.exMode) return;
var head = cur.head;
if (head.ch && head.ch == cm.doc.getLine(head.line).length) {
head.ch--;
}
}
var numberRegex = /[\d]/;
var wordRegexp = [(/\w/), (/[^\w\s]/)], bigWordRegexp = [(/\S/)];
function makeKeyRange(start, size) {
@@ -450,28 +476,11 @@
};
};
// Global Vim state. Call getVimGlobalState to get and initialize.
var vimGlobalState;
function getVimGlobalState() {
if (!vimGlobalState) {
vimGlobalState = {
// The current search query.
searchQuery: null,
// Whether we are searching backwards.
searchIsReversed: false,
jumpList: createCircularJumpList(),
macroModeState: createMacroState(),
// Recording latest f, t, F or T motion command.
lastChararacterSearch: {increment:0, forward:true, selectedCharacter:''},
registerController: new RegisterController({})
};
}
return vimGlobalState;
}
function getVimState(cm) {
if (!cm.vimState) {
function maybeInitVimState(cm) {
if (!cm.state.vim) {
// Store instance state in the CodeMirror object.
cm.vimState = {
cm.state.vim = {
inputState: new InputState(),
// Vim's input state that triggered the last edit, used to repeat
// motions and operators with '.'.
@@ -500,7 +509,21 @@
visualLine: false
};
}
return cm.vimState;
return cm.state.vim;
}
var vimGlobalState;
function resetVimGlobalState() {
vimGlobalState = {
// The current search query.
searchQuery: null,
// Whether we are searching backwards.
searchIsReversed: false,
jumpList: createCircularJumpList(),
macroModeState: createMacroState(),
// Recording latest f, t, F or T motion command.
lastChararacterSearch: {increment:0, forward:true, selectedCharacter:''},
registerController: new RegisterController({})
};
}
var vimApi= {
@@ -510,16 +533,19 @@
// Testing hook, though it might be useful to expose the register
// controller anyways.
getRegisterController: function() {
return getVimGlobalState().registerController;
return vimGlobalState.registerController;
},
// Testing hook.
clearVimGlobalState_: function() {
vimGlobalState = null;
},
resetVimGlobalState_: resetVimGlobalState,
// Testing hook.
getVimGlobalState_: function() {
return vimGlobalState;
},
// Testing hook.
maybeInitVimState_: maybeInitVimState,
InsertModeKey: InsertModeKey,
map: function(lhs, rhs) {
// Add user defined key bindings.
@@ -532,17 +558,12 @@
exCommands[name]=func;
exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'};
},
// Initializes vim state variable on the CodeMirror object. Should only be
// called lazily by handleKey or for testing.
maybeInitState: function(cm) {
getVimState(cm);
},
// This is the outermost function called by CodeMirror, after keys have
// been mapped to their Vim equivalents.
handleKey: function(cm, key) {
var command;
var vim = getVimState(cm);
var macroModeState = getVimGlobalState().macroModeState;
var vim = maybeInitVimState(cm);
var macroModeState = vimGlobalState.macroModeState;
if (macroModeState.enteredMacroMode) {
if (key == 'q') {
actions.exitMacroRecordMode();
@@ -554,19 +575,17 @@
// Clear input state and get back to normal mode.
vim.inputState = new InputState();
if (vim.visualMode) {
exitVisualMode(cm, vim);
exitVisualMode(cm);
}
return;
}
if (vim.visualMode &&
cursorEqual(cm.getCursor('head'), cm.getCursor('anchor'))) {
// The selection was cleared. Exit visual mode.
exitVisualMode(cm, vim);
}
// Enter visual mode when the mouse selects text.
if (!vim.visualMode &&
!cursorEqual(cm.getCursor('head'), cm.getCursor('anchor'))) {
vim.visualMode = true;
vim.visualLine = false;
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"});
cm.on('mousedown', exitVisualMode);
}
if (key != '0' || (key == '0' && vim.inputState.getRepeat() === 0)) {
// Have to special case 0 since it's both a motion and a number.
@@ -970,7 +989,7 @@
// cachedCursor is used to save the old position of the cursor
// when * or # causes vim to seek for the nearest word and shift
// the cursor before entering the motion.
getVimGlobalState().jumpList.cachedCursor = cm.getCursor();
vimGlobalState.jumpList.cachedCursor = cm.getCursor();
cm.setCursor(word.start);
handleQuery(query, true /** ignoreCase */, false /** smartCase */);
@@ -1052,7 +1071,7 @@
return;
}
if (motionArgs.toJumplist) {
var jumpList = getVimGlobalState().jumpList;
var jumpList = vimGlobalState.jumpList;
// if the current motion is # or *, use cachedCursor
var cachedCursor = jumpList.cachedCursor;
if (cachedCursor) {
@@ -1091,6 +1110,11 @@
if (vim.visualLine) {
if (cursorIsBefore(selectionStart, selectionEnd)) {
selectionStart.ch = 0;
var lastLine = cm.lastLine();
if (selectionEnd.line > lastLine) {
selectionEnd.line = lastLine;
}
selectionEnd.ch = lineLength(cm, selectionEnd.line);
} else {
selectionEnd.ch = 0;
@@ -1146,15 +1170,12 @@
operators[operator](cm, operatorArgs, vim, curStart,
curEnd, curOriginal);
if (vim.visualMode) {
exitVisualMode(cm, vim);
}
if (operatorArgs.enterInsertMode) {
actions.enterInsertMode(cm, {}, vim);
exitVisualMode(cm);
}
}
},
recordLastEdit: function(vim, inputState, actionCommand) {
var macroModeState = getVimGlobalState().macroModeState;
var macroModeState = vimGlobalState.macroModeState;
if (macroModeState.inReplay) { return; }
vim.lastEditInputState = inputState;
vim.lastEditActionCommand = actionCommand;
@@ -1272,8 +1293,13 @@
}
var repeat = motionArgs.repeat+(motionArgs.repeatOffset||0);
var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat;
if (line < cm.firstLine() || line > cm.lastLine() ) {
return null;
var first = cm.firstLine();
var last = cm.lastLine();
// Vim cancels linewise motions that start on an edge and move beyond
// that edge. It does not cancel motions that do not start on an edge.
if ((line < first && cur.line == first) ||
(line > last && cur.line == last)) {
return;
}
if(motionArgs.toFirstChar){
endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));
@@ -1456,7 +1482,7 @@
return [start, end];
},
repeatLastCharacterSearch: function(cm, motionArgs) {
var lastSearch = getVimGlobalState().lastChararacterSearch;
var lastSearch = vimGlobalState.lastChararacterSearch;
var repeat = motionArgs.repeat;
var forward = motionArgs.forward === lastSearch.forward;
var increment = (lastSearch.increment ? 1 : 0) * (forward ? -1 : 1);
@@ -1474,22 +1500,16 @@
var operators = {
change: function(cm, operatorArgs, _vim, curStart, curEnd) {
getVimGlobalState().registerController.pushText(
vimGlobalState.registerController.pushText(
operatorArgs.registerName, 'change', cm.getRange(curStart, curEnd),
operatorArgs.linewise);
if (operatorArgs.linewise) {
// Delete starting at the first nonwhitespace character of the first
// line, instead of from the start of the first line. This way we get
// an indent when we get into insert mode. This behavior isn't quite
// correct because we should treat this as a completely new line, and
// indent should be whatever codemirror thinks is the right indent.
// But cm.indentLine doesn't seem work on empty lines.
// TODO: Fix the above.
curStart.ch =
findFirstNonWhiteSpaceCharacter(cm.getLine(curStart.line));
// Insert an additional newline so that insert mode can start there.
// curEnd should be on the first character of the new line.
cm.replaceRange('\n', curStart, curEnd);
// Push the next line back down, if there is a next line.
var replacement = curEnd.line > cm.lastLine() ? '' : '\n';
cm.replaceRange(replacement, curStart, curEnd);
cm.indentLine(curStart.line, 'smart');
// null ch so setCursor moves to end of line.
curStart.ch = null;
} else {
// Exclude trailing whitespace if the range is not all whitespace.
var text = cm.getRange(curStart, curEnd);
@@ -1501,6 +1521,7 @@
}
cm.replaceRange('', curStart, curEnd);
}
actions.enterInsertMode(cm, {}, cm.state.vim);
cm.setCursor(curStart);
},
// delete is a javascript keyword.
@@ -1512,7 +1533,7 @@
curStart.line--;
curStart.ch = lineLength(cm, curStart.line);
}
getVimGlobalState().registerController.pushText(
vimGlobalState.registerController.pushText(
operatorArgs.registerName, 'delete', cm.getRange(curStart, curEnd),
operatorArgs.linewise);
cm.replaceRange('', curStart, curEnd);
@@ -1542,7 +1563,7 @@
cm.setCursor(curStart);
cm.setCursor(motions.moveToFirstNonWhiteSpaceCharacter(cm));
},
swapcase: function(cm, _operatorArgs, _vim, curStart, curEnd, curOriginal) {
swapcase: function(cm, operatorArgs, _vim, curStart, curEnd, curOriginal) {
var toSwap = cm.getRange(curStart, curEnd);
var swapped = '';
for (var i = 0; i < toSwap.length; i++) {
@@ -1551,10 +1572,12 @@
character.toUpperCase();
}
cm.replaceRange(swapped, curStart, curEnd);
cm.setCursor(curOriginal);
if (!operatorArgs.shouldMoveCursor) {
cm.setCursor(curOriginal);
}
},
yank: function(cm, operatorArgs, _vim, curStart, curEnd, curOriginal) {
getVimGlobalState().registerController.pushText(
vimGlobalState.registerController.pushText(
operatorArgs.registerName, 'yank',
cm.getRange(curStart, curEnd), operatorArgs.linewise);
cm.setCursor(curOriginal);
@@ -1568,7 +1591,7 @@
}
var repeat = actionArgs.repeat;
var forward = actionArgs.forward;
var jumpList = getVimGlobalState().jumpList;
var jumpList = vimGlobalState.jumpList;
var mark = jumpList.move(cm, forward ? repeat : -repeat);
var markPos = mark ? mark.find() : undefined;
@@ -1594,7 +1617,7 @@
replayMacro: function(cm, actionArgs) {
var registerName = actionArgs.selectedCharacter;
var repeat = actionArgs.repeat;
var macroModeState = getVimGlobalState().macroModeState;
var macroModeState = vimGlobalState.macroModeState;
if (registerName == '@') {
registerName = macroModeState.latestRegister;
}
@@ -1604,18 +1627,19 @@
}
},
exitMacroRecordMode: function() {
var macroModeState = getVimGlobalState().macroModeState;
var macroModeState = vimGlobalState.macroModeState;
macroModeState.toggle();
parseKeyBufferToRegister(macroModeState.latestRegister,
macroModeState.macroKeyBuffer);
},
enterMacroRecordMode: function(cm, actionArgs) {
var macroModeState = getVimGlobalState().macroModeState;
var macroModeState = vimGlobalState.macroModeState;
var registerName = actionArgs.selectedCharacter;
macroModeState.toggle(cm, registerName);
emptyMacroKeyBuffer(macroModeState);
},
enterInsertMode: function(cm, actionArgs, vim) {
if (cm.getOption('readOnly')) { return; }
vim.insertMode = true;
vim.insertModeRepeat = actionArgs && actionArgs.repeat || 1;
var insertAt = (actionArgs) ? actionArgs.insertAt : null;
@@ -1633,10 +1657,12 @@
// Handle Replace-mode as a special case of insert mode.
cm.toggleOverwrite(true);
cm.setOption('keyMap', 'vim-replace');
CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"});
} else {
cm.setOption('keyMap', 'vim-insert');
CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"});
}
if (!getVimGlobalState().macroModeState.inReplay) {
if (!vimGlobalState.macroModeState.inReplay) {
// Only record if not replaying.
cm.on('change', onChange);
cm.on('cursorActivity', onCursorActivity);
@@ -1651,6 +1677,7 @@
// equal to the repeat times the size of the previous visual
// operation.
if (!vim.visualMode) {
cm.on('mousedown', exitVisualMode);
vim.visualMode = true;
vim.visualLine = !!actionArgs.linewise;
if (vim.visualLine) {
@@ -1675,6 +1702,7 @@
} else {
cm.setSelection(curStart, curEnd);
}
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : ""});
} else {
curStart = cm.getCursor('anchor');
curEnd = cm.getCursor('head');
@@ -1687,12 +1715,14 @@
curEnd.ch = cursorIsBefore(curStart, curEnd) ?
lineLength(cm, curEnd.line) : 0;
cm.setSelection(curStart, curEnd);
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: "linewise"});
} else if (vim.visualLine && !actionArgs.linewise) {
// v pressed in linewise visual mode. Switch to characterwise visual
// mode instead of exiting visual mode.
vim.visualLine = false;
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"});
} else {
exitVisualMode(cm, vim);
exitVisualMode(cm);
}
}
updateMark(cm, vim, '<', cursorIsBefore(curStart, curEnd) ? curStart
@@ -1728,6 +1758,7 @@
});
},
newLineAndEnterInsertMode: function(cm, actionArgs, vim) {
vim.insertMode = true;
var insertAt = cm.getCursor();
if (insertAt.line === cm.firstLine() && !actionArgs.after) {
// Special case for inserting newline before start of document.
@@ -1746,7 +1777,7 @@
},
paste: function(cm, actionArgs) {
var cur = cm.getCursor();
var register = getVimGlobalState().registerController.getRegister(
var register = vimGlobalState.registerController.getRegister(
actionArgs.registerName);
if (!register.text) {
return;
@@ -1832,7 +1863,7 @@
cm.replaceRange(replaceWithStr, curStart, curEnd);
if(vim.visualMode){
cm.setCursor(curStart);
exitVisualMode(cm,vim);
exitVisualMode(cm);
}else{
cm.setCursor(offsetCursor(curEnd, 0, -1));
}
@@ -1989,7 +2020,9 @@
return s.replace(/([.?*+$\[\]\/\\(){}|\-])/g, '\\$1');
}
function exitVisualMode(cm, vim) {
function exitVisualMode(cm) {
cm.off('mousedown', exitVisualMode);
var vim = cm.state.vim;
vim.visualMode = false;
vim.visualLine = false;
var selectionStart = cm.getCursor('anchor');
@@ -2000,6 +2033,7 @@
// it's not supposed to be.
cm.setCursor(clipCursorToContent(cm, selectionEnd));
}
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
}
// Remove any trailing newlines from the selection. For
@@ -2113,12 +2147,11 @@
function recordJumpPosition(cm, oldCur, newCur) {
if(!cursorEqual(oldCur, newCur)) {
getVimGlobalState().jumpList.add(cm, oldCur, newCur);
vimGlobalState.jumpList.add(cm, oldCur, newCur);
}
}
function recordLastCharacterSearch(increment, args) {
var vimGlobalState = getVimGlobalState();
vimGlobalState.lastChararacterSearch.increment = increment;
vimGlobalState.lastChararacterSearch.forward = args.forward;
vimGlobalState.lastChararacterSearch.selectedCharacter = args.selectedCharacter;
@@ -2572,10 +2605,10 @@
function SearchState() {}
SearchState.prototype = {
getQuery: function() {
return getVimGlobalState().query;
return vimGlobalState.query;
},
setQuery: function(query) {
getVimGlobalState().query = query;
vimGlobalState.query = query;
},
getOverlay: function() {
return this.searchOverlay;
@@ -2584,14 +2617,14 @@
this.searchOverlay = overlay;
},
isReversed: function() {
return getVimGlobalState().isReversed;
return vimGlobalState.isReversed;
},
setReversed: function(reversed) {
getVimGlobalState().isReversed = reversed;
vimGlobalState.isReversed = reversed;
}
};
function getSearchState(cm) {
var vim = getVimState(cm);
var vim = cm.state.vim;
return vim.searchState_ || (vim.searchState_ = new SearchState());
}
function dialog(cm, template, shortText, onClose, options) {
@@ -2840,9 +2873,9 @@
};
Vim.ExCommandDispatcher.prototype = {
processCommand: function(cm, input) {
var vim = getVimState(cm);
var vim = cm.state.vim;
if (vim.visualMode) {
exitVisualMode(cm, vim);
exitVisualMode(cm);
}
var inputStream = new CodeMirror.StringStream(input);
var params = {};
@@ -2921,7 +2954,7 @@
case '$':
return cm.lastLine();
case '\'':
var mark = getVimState(cm).marks[inputStream.next()];
var mark = cm.state.vim.marks[inputStream.next()];
if (mark && mark.find()) {
return mark.find().line;
}
@@ -3031,7 +3064,7 @@
exCommandDispatcher.map(mapArgs[0], mapArgs[1], cm);
},
move: function(cm, params) {
commandDispatcher.processCommand(cm, getVimState(cm), {
commandDispatcher.processCommand(cm, cm.state.vim, {
type: 'motion',
motion: 'moveToLineOrEdgeOfDocument',
motionArgs: { forward: false, explicitRepeat: true,
@@ -3186,7 +3219,7 @@
return;
}
var state = getVimState(cm);
var state = cm.state.vim;
var stream = new CodeMirror.StringStream(params.argString.trim());
while (!stream.eol()) {
stream.eatSpace();
@@ -3257,6 +3290,7 @@
function doReplace(cm, confirm, lineStart, lineEnd, searchCursor, query,
replaceWith) {
// Set up all the functions.
cm.state.vim.exMode = true;
var done = false;
var lastPos = searchCursor.from();
function replaceAll() {
@@ -3291,7 +3325,8 @@
cm.focus();
if (lastPos) {
cm.setCursor(lastPos);
var vim = getVimState(cm);
var vim = cm.state.vim;
vim.exMode = false;
vim.lastHPos = vim.lastHSPos = lastPos.ch;
}
}
@@ -3403,9 +3438,8 @@
CodeMirror.keyMap.vim = buildVimKeyMap();
function exitInsertMode(cm) {
var vim = getVimState(cm);
vim.insertMode = false;
var inReplay = getVimGlobalState().macroModeState.inReplay;
var vim = cm.state.vim;
var inReplay = vimGlobalState.macroModeState.inReplay;
if (!inReplay) {
cm.off('change', onChange);
cm.off('cursorActivity', onCursorActivity);
@@ -3419,8 +3453,10 @@
}
delete vim.insertModeRepeat;
cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
vim.insertMode = false;
cm.setOption('keyMap', 'vim');
cm.toggleOverwrite(false); // exit replace mode if we were in it.
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
}
CodeMirror.keyMap['vim-insert'] = {
@@ -3446,7 +3482,7 @@
function parseRegisterToKeyBuffer(macroModeState, registerName) {
var match, key;
var register = getVimGlobalState().registerController.getRegister(registerName);
var register = vimGlobalState.registerController.getRegister(registerName);
var text = register.toString();
var macroKeyBuffer = macroModeState.macroKeyBuffer;
emptyMacroKeyBuffer(macroModeState);
@@ -3462,7 +3498,7 @@
function parseKeyBufferToRegister(registerName, keyBuffer) {
var text = keyBuffer.join('');
getVimGlobalState().registerController.setRegisterText(registerName, text);
vimGlobalState.registerController.setRegisterText(registerName, text);
}
function emptyMacroKeyBuffer(macroModeState) {
@@ -3490,7 +3526,7 @@
* Should only be active in insert mode.
*/
function onChange(_cm, changeObj) {
var macroModeState = getVimGlobalState().macroModeState;
var macroModeState = vimGlobalState.macroModeState;
var lastChange = macroModeState.lastInsertModeChanges;
while (changeObj) {
lastChange.expectCursorActivityForChange = true;
@@ -3510,7 +3546,7 @@
* - Should only be active in insert mode.
*/
function onCursorActivity() {
var macroModeState = getVimGlobalState().macroModeState;
var macroModeState = vimGlobalState.macroModeState;
var lastChange = macroModeState.lastInsertModeChanges;
if (lastChange.expectCursorActivityForChange) {
lastChange.expectCursorActivityForChange = false;
@@ -3531,7 +3567,7 @@
* - For recording deletes in insert mode.
*/
function onKeyEventTargetKeyDown(e) {
var macroModeState = getVimGlobalState().macroModeState;
var macroModeState = vimGlobalState.macroModeState;
var lastChange = macroModeState.lastInsertModeChanges;
var keyName = CodeMirror.keyName(e);
function onKeyFound() {
@@ -3553,7 +3589,7 @@
* corresponding enterInsertMode call was made with a count.
*/
function repeatLastEdit(cm, vim, repeat, repeatForInsert) {
var macroModeState = getVimGlobalState().macroModeState;
var macroModeState = vimGlobalState.macroModeState;
macroModeState.inReplay = true;
var isAction = !!vim.lastEditActionCommand;
var cachedInputState = vim.inputState;
@@ -3621,6 +3657,7 @@
}
}
resetVimGlobalState();
return vimApi;
};
// Initialize Vim and make it available as an API.

View File

@@ -95,6 +95,7 @@
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
@@ -117,6 +118,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-sizer {
position: relative;
@@ -155,6 +158,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
-moz-box-sizing: content-box;
box-sizing: content-box;
padding-bottom: 30px;
margin-bottom: -32px;
display: inline-block;
@@ -192,6 +197,16 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
white-space: pre-wrap;
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 {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
@@ -204,8 +219,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
overflow: auto;
}
.CodeMirror-widget {
}
.CodeMirror-widget {}
.CodeMirror-wrap .CodeMirror-scroll {
overflow-x: hidden;
@@ -213,7 +227,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-measure {
position: absolute;
width: 100%; height: 0px;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,32 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: APL mode</title>
<link rel="stylesheet" href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="./apl.js"></script>
<style>
<title>CodeMirror: APL 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="../../addon/edit/matchbrackets.js"></script>
<script src="./apl.js"></script>
<style>
.CodeMirror { border: 2px inset #dee; }
</style>
</head>
<body>
<h1>CodeMirror: APL mode</h1>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">APL</a>
</ul>
</div>
<article>
<h2>APL mode</h2>
<form><textarea id="code" name="code">
⍝ Conway's game of life
@@ -57,5 +69,4 @@ gen ← {' #'[(life ⍣ ⍵) board]}
have popups etc.</p>
<p><strong>MIME types defined:</strong> <code>text/apl</code> (APL code)</p>
</body>
</html>
</article>

View File

@@ -1,20 +1,33 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Asterisk dialplan mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="asterisk.js"></script>
<style>
<title>CodeMirror: Asterisk dialplan 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="asterisk.js"></script>
<style>
.CodeMirror {border: 1px solid #999;}
.cm-s-default span.cm-arrow { color: red; }
</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Asterisk dialplan mode</h1>
<form><textarea id="code" name="code">
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Asterisk dialplan</a>
</ul>
</div>
<article>
<h2>Asterisk dialplan mode</h2>
<form><textarea id="code" name="code">
; extensions.conf - the Asterisk dial plan
;
@@ -138,5 +151,4 @@ exten => 8500,n,Goto(s,6)
<p><strong>MIME types defined:</strong> <code>text/x-asterisk</code>.</p>
</body>
</html>
</article>

View File

@@ -158,7 +158,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
electricChars: "{}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//"
lineComment: "//",
fold: "brace"
};
});

View File

@@ -1,19 +1,32 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: C-like mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="clike.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border: 2px inset #dee;}</style>
</head>
<body>
<h1>CodeMirror: C-like mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: C-like 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="../../addon/edit/matchbrackets.js"></script>
<script src="clike.js"></script>
<style>.CodeMirror {border: 2px inset #dee;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">C-like</a>
</ul>
</div>
<article>
<h2>C-like mode</h2>
<div><textarea id="c-code">
/* C demo code */
#include <zmq.h>
@@ -79,14 +92,94 @@ void* zmq_thread_init(void* zmq_context, int signal_fd) {
pthread_detach(thread);
return context;
}
</textarea></form>
</textarea></div>
<h2>C++ example</h2>
<div><textarea id="cpp-code">
#include <iostream>
#include "mystuff/util.h"
namespace {
enum Enum {
VAL1, VAL2, VAL3
};
int Helper(const MyType& param) {
return 0;
}
} // namespace
class ForwardDec;
template <class T, class V>
class Class : public BaseClass {
const MyType<T, V> member_;
public:
const MyType<T, V>& Method() const {
return member_;
}
void Method2(MyType<T, V>* value);
}
template <class T, class V>
void Class::Method2(MyType<T, V>* value) {
std::out << 1 >> method();
value->Method3(member_);
member_ = value;
}
</textarea></div>
<h2>Java example</h2>
<div><textarea id="java-code">
import com.demo.util.MyType;
import com.demo.util.MyInterface;
public enum Enum {
VAL1, VAL2, VAL3
}
public class Class<T, V> implements MyInterface {
public static final MyType<T, V> member;
private class InnerClass {
public int zero() {
return 0;
}
}
@Override
public MyType method() {
return member;
}
public void method2(MyType<T, V> value) {
method();
value.method3();
member = value;
}
}
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
var editor = CodeMirror.fromTextArea(document.getElementById("c-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-csrc"
});
var editor = CodeMirror.fromTextArea(document.getElementById("cpp-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-c++src"
});
var javaEditor = CodeMirror.fromTextArea(document.getElementById("java-code"), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-java"
});
</script>
<p>Simple mode that tries to handle C-like languages as well as it
@@ -99,5 +192,4 @@ void* zmq_thread_init(void* zmq_context, int signal_fd) {
(C code), <code>text/x-c++src</code> (C++
code), <code>text/x-java</code> (Java
code), <code>text/x-csharp</code> (C#).</p>
</body>
</html>
</article>

View File

@@ -1,29 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: C-like mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/ambiance.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="clike.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>
body
{
margin: 0;
padding: 0;
max-width:inherit;
height: 100%;
}
html, form, .CodeMirror, .CodeMirror-scroll
{
height: 100%;
}
</style>
</head>
<body>
<title>CodeMirror: Scala mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/ambiance.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="clike.js"></script>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Scala</a>
</ul>
</div>
<article>
<h2>Scala mode</h2>
<form>
<textarea id="code" name="code">
@@ -763,5 +764,4 @@
mode: "text/x-scala"
});
</script>
</body>
</html>
</article>

View File

@@ -1,17 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Clojure mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="clojure.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Clojure mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: Clojure 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="clojure.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Clojure</a>
</ul>
</div>
<article>
<h2>Clojure mode</h2>
<form><textarea id="code" name="code">
; Conway's Game of Life, based on the work of:
;; Laurent Petit https://gist.github.com/1200343
;; Christophe Grand http://clj-me.cgrand.net/2011/08/19/conways-game-of-life
@@ -72,5 +85,4 @@
<p><strong>MIME types defined:</strong> <code>text/x-clojure</code>.</p>
</body>
</html>
</article>

View File

@@ -1,35 +1,36 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: COBOL mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="cobol.js"></script>
<link rel="stylesheet" href="../../theme/neat.css">
<link rel="stylesheet" href="../../theme/elegant.css">
<link rel="stylesheet" href="../../theme/erlang-dark.css">
<link rel="stylesheet" href="../../theme/night.css">
<link rel="stylesheet" href="../../theme/monokai.css">
<link rel="stylesheet" href="../../theme/cobalt.css">
<link rel="stylesheet" href="../../theme/eclipse.css">
<link rel="stylesheet" href="../../theme/rubyblue.css">
<link rel="stylesheet" href="../../theme/lesser-dark.css">
<link rel="stylesheet" href="../../theme/xq-dark.css">
<link rel="stylesheet" href="../../theme/xq-light.css">
<link rel="stylesheet" href="../../theme/ambiance.css">
<link rel="stylesheet" href="../../theme/blackboard.css">
<link rel="stylesheet" href="../../theme/vibrant-ink.css">
<link rel="stylesheet" href="../../theme/solarized.css">
<link rel="stylesheet" href="../../theme/twilight.css">
<link rel="stylesheet" href="../../theme/midnight.css">
<link rel="stylesheet" href="../../addon/dialog/dialog.css">
<script src="../../addon/selection/active-line.js"></script>
<script src="../../addon/search/search.js"></script>
<script src="../../addon/dialog/dialog.js"></script>
<script src="../../addon/search/searchcursor.js"></script>
<style>
<title>CodeMirror: COBOL mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/neat.css">
<link rel="stylesheet" href="../../theme/elegant.css">
<link rel="stylesheet" href="../../theme/erlang-dark.css">
<link rel="stylesheet" href="../../theme/night.css">
<link rel="stylesheet" href="../../theme/monokai.css">
<link rel="stylesheet" href="../../theme/cobalt.css">
<link rel="stylesheet" href="../../theme/eclipse.css">
<link rel="stylesheet" href="../../theme/rubyblue.css">
<link rel="stylesheet" href="../../theme/lesser-dark.css">
<link rel="stylesheet" href="../../theme/xq-dark.css">
<link rel="stylesheet" href="../../theme/xq-light.css">
<link rel="stylesheet" href="../../theme/ambiance.css">
<link rel="stylesheet" href="../../theme/blackboard.css">
<link rel="stylesheet" href="../../theme/vibrant-ink.css">
<link rel="stylesheet" href="../../theme/solarized.css">
<link rel="stylesheet" href="../../theme/twilight.css">
<link rel="stylesheet" href="../../theme/midnight.css">
<link rel="stylesheet" href="../../addon/dialog/dialog.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="cobol.js"></script>
<script src="../../addon/selection/active-line.js"></script>
<script src="../../addon/search/search.js"></script>
<script src="../../addon/dialog/dialog.js"></script>
<script src="../../addon/search/searchcursor.js"></script>
<style>
.CodeMirror {
border: 1px solid #eee;
font-size : 20px;
@@ -37,8 +38,23 @@
}
.CodeMirror-activeline-background {background: #555555 !important;}
</style>
</head>
<body>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">COBOL</a>
</ul>
</div>
<article>
<h2>COBOL mode</h2>
<p> Select Theme <select onchange="selectTheme()" id="selectTheme">
<option>default</option>
<option>ambiance</option>
@@ -191,5 +207,4 @@
}
}
</script>
</body>
</html>
</article>

View File

@@ -1,22 +0,0 @@
The MIT License
Copyright (c) 2011 Jeff Pickhardt
Modified from the Python CodeMirror mode, Copyright (c) 2010 Timothy Farrell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -259,7 +259,7 @@ CodeMirror.defineMode('coffeescript', function(conf) {
if (current === '.') {
style = state.tokenize(stream, state);
current = stream.current();
if (style === 'variable') {
if (/^\.[\w$]+$/.test(current)) {
return 'variable';
} else {
return ERRORCLASS;
@@ -339,7 +339,8 @@ CodeMirror.defineMode('coffeescript', function(conf) {
return state.scopes[0].offset;
},
lineComment: "#"
lineComment: "#",
fold: "indent"
};
return external;
});

View File

@@ -1,17 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: CoffeeScript mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="coffeescript.js"></script>
<style>.CodeMirror {border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: CoffeeScript mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: CoffeeScript 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="coffeescript.js"></script>
<style>.CodeMirror {border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">CoffeeScript</a>
</ul>
</div>
<article>
<h2>CoffeeScript mode</h2>
<form><textarea id="code" name="code">
# CoffeeScript mode for CodeMirror
# Copyright (c) 2011 Jeff Pickhardt, released under
# the MIT License.
@@ -724,5 +737,4 @@ wrapper::value = -> this._wrapped
<p>The CoffeeScript mode was written by Jeff Pickhardt (<a href="LICENSE">license</a>).</p>
</body>
</html>
</article>

View File

@@ -1,17 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Common Lisp mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="commonlisp.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Common Lisp mode</h1>
<form><textarea id="code" name="code">(in-package :cl-postgres)
<title>CodeMirror: Common Lisp 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="commonlisp.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Common Lisp</a>
</ul>
</div>
<article>
<h2>Common Lisp mode</h2>
<form><textarea id="code" name="code">(in-package :cl-postgres)
;; These are used to synthesize reader and writer names for integer
;; reading/writing functions when the amount of bytes and the
@@ -161,5 +174,4 @@ when UTF-8 support is enabled."
<p><strong>MIME types defined:</strong> <code>text/x-common-lisp</code>.</p>
</body>
</html>
</article>

View File

@@ -1,10 +1,8 @@
CodeMirror.defineMode("css", function(config) {
return CodeMirror.getMode(config, "text/css");
});
CodeMirror.defineMode("css-base", function(config, parserConfig) {
CodeMirror.defineMode("css", function(config, parserConfig) {
"use strict";
if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
var indentUnit = config.indentUnit,
hooks = parserConfig.hooks || {},
atMediaTypes = parserConfig.atMediaTypes || {},
@@ -39,7 +37,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
stream.match(/^\s*\w*/);
return ret("keyword", "important");
}
else if (/\d/.test(ch)) {
else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
}
@@ -103,7 +101,8 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
startState: function(base) {
return {tokenize: tokenBase,
baseIndent: base || 0,
stack: []};
stack: [],
lastToken: null};
},
token: function(stream, state) {
@@ -163,7 +162,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
var context = state.stack[state.stack.length-1];
if (style == "variable") {
if (type == "variable-definition") state.stack.push("propertyValue");
return "variable-2";
return state.lastToken = "variable-2";
} else if (style == "property") {
var word = stream.current().toLowerCase();
if (context == "propertyValue") {
@@ -251,7 +250,6 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
// Push/pop context stack
if (type == "{") {
if (context == "@media" || context == "@mediaType") {
state.stack.pop();
state.stack[state.stack.length-1] = "@media{";
}
else {
@@ -260,8 +258,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
}
}
else if (type == "}") {
var lastState = state.stack[state.stack.length - 1];
if (lastState == "interpolation") style = "operator";
if (context == "interpolation") style = "operator";
state.stack.pop();
if (context == "propertyValue") state.stack.pop();
}
@@ -269,26 +266,42 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
else if (type == "@media") state.stack.push("@media");
else if (type == "@import") state.stack.push("@import");
else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
state.stack.push("@mediaType");
else if (context == "@mediaType" && stream.current() == ",") state.stack.pop();
else if (context == "@mediaType" && type == "(") state.stack.push("@mediaType(");
else if (context == "@mediaType(" && type == ")") state.stack.pop();
else if ((context == "rule" || context == "block") && type == ":") state.stack.push("propertyValue");
state.stack[state.stack.length-1] = "@mediaType";
else if (context == "@mediaType" && stream.current() == ",")
state.stack[state.stack.length-1] = "@media";
else if (type == "(") {
if (context == "@media" || context == "@mediaType") {
// Make sure @mediaType is used to avoid error on {
state.stack[state.stack.length-1] = "@mediaType";
state.stack.push("@mediaType(");
}
else state.stack.push("(");
}
else if (type == ")") {
if (context == "propertyValue") {
// In @mediaType( without closing ; after propertyValue
state.stack.pop();
}
state.stack.pop();
}
else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
else if (context == "propertyValue" && type == ";") state.stack.pop();
else if (context == "@import" && type == ";") state.stack.pop();
return style;
return state.lastToken = style;
},
indent: function(state, textAfter) {
var n = state.stack.length;
if (/^\}/.test(textAfter))
n -= state.stack[state.stack.length-1] == "propertyValue" ? 2 : 1;
n -= state.stack[n-1] == "propertyValue" ? 2 : 1;
return state.baseIndent + n * indentUnit;
},
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/"
blockCommentEnd: "*/",
fold: "brace"
};
});
@@ -349,8 +362,8 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
"float", "float-offset", "font", "font-feature-settings", "font-family",
"font-kerning", "font-language-override", "font-size", "font-size-adjust",
"float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
"font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
"font-stretch", "font-style", "font-synthesis", "font-variant",
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
@@ -374,25 +387,27 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"page", "page-break-after", "page-break-before", "page-break-inside",
"page-policy", "pause", "pause-after", "pause-before", "perspective",
"perspective-origin", "pitch", "pitch-range", "play-during", "position",
"presentation-level", "punctuation-trim", "quotes", "rendering-intent",
"resize", "rest", "rest-after", "rest-before", "richness", "right",
"rotation", "rotation-point", "ruby-align", "ruby-overhang",
"ruby-position", "ruby-span", "size", "speak", "speak-as", "speak-header",
"presentation-level", "punctuation-trim", "quotes", "region-break-after",
"region-break-before", "region-break-inside", "region-fragment",
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
"ruby-position", "ruby-span", "shape-inside", "shape-outside", "size",
"speak", "speak-as", "speak-header",
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
"tab-size", "table-layout", "target", "target-name", "target-new",
"target-position", "text-align", "text-align-last", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-style", "text-emphasis", "text-emphasis-color",
"text-emphasis-position", "text-emphasis-style", "text-height",
"text-indent", "text-justify", "text-outline", "text-shadow",
"text-space-collapse", "text-transform", "text-underline-position",
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
"text-wrap", "top", "transform", "transform-origin", "transform-style",
"transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "unicode-bidi",
"vertical-align", "visibility", "voice-balance", "voice-duration",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
"voice-volume", "volume", "white-space", "widows", "width", "word-break",
"word-spacing", "word-wrap", "z-index",
"word-spacing", "word-wrap", "z-index", "zoom",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
@@ -415,7 +430,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
"deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
"gold", "goldenrod", "gray", "green", "greenyellow", "honeydew",
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
@@ -438,22 +453,22 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"above", "absolute", "activeborder", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "auto", "avoid", "background",
"backwards", "baseline", "below", "bidi-override", "binary", "bengali",
"blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
"both", "bottom", "break-all", "break-word", "button", "button-bevel",
"arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
"both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "compact", "condensed", "contain", "content",
"col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
"content-box", "context-menu", "continuous", "copy", "cover", "crop",
"cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari",
"disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
"double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
@@ -469,7 +484,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
"italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer",
"italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
"landscape", "lao", "large", "larger", "left", "level", "lighter",
"line-through", "linear", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
@@ -488,11 +503,11 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "overlay", "overline", "padding", "padding-box", "painted",
"paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait",
"pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
"radio", "read-only", "read-write", "read-write-plaintext-only", "relative",
"repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
"painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
"polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
"radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
"relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
"ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
"s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
@@ -563,7 +578,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
return false;
}
},
name: "css-base"
name: "css"
});
CodeMirror.defineMIME("text/x-scss", {
@@ -574,6 +589,12 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
valueKeywords: valueKeywords,
allowNested: true,
hooks: {
":": function(stream) {
if (stream.match(/\s*{/)) {
return [null, "{"];
}
return false;
},
"$": function(stream) {
stream.match(/^[\w-]+/);
if (stream.peek() == ":") {
@@ -601,6 +622,6 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
}
}
},
name: "css-base"
name: "css"
});
})();

View File

@@ -1,17 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: CSS mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: CSS mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: CSS 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="css.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">CSS</a>
</ul>
</div>
<article>
<h2>CSS mode</h2>
<form><textarea id="code" name="code">
/* Some example CSS */
@import url("something.css");
@@ -54,5 +67,4 @@ code {
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#css_*">normal</a>, <a href="../../test/index.html#verbose,css_*">verbose</a>.</p>
</body>
</html>
</article>

View File

@@ -1,17 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: SCSS mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: SCSS mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: SCSS 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="css.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">SCSS</a>
</ul>
</div>
<article>
<h2>SCSS mode</h2>
<form><textarea id="code" name="code">
/* Some example SCSS */
@import "compass/css3";
@@ -141,5 +154,4 @@ code {
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#scss_*">normal</a>, <a href="../../test/index.html#verbose,scss_*">verbose</a>.</p>
</body>
</html>
</article>

View File

@@ -64,7 +64,7 @@
"[tag p] { [tag a] { [property color][operator :][atom #000]; } }");
MT('interpolation_in_property',
"[tag foo] { [operator #{][variable-2 $hello][operator }:][atom #000]; }");
"[tag foo] { [operator #{][variable-2 $hello][operator }:][number 2]; }");
MT('interpolation_in_selector',
"[tag foo][operator #{][variable-2 $hello][operator }] { [property color][operator :][atom #000]; }");

View File

@@ -15,6 +15,12 @@
MT("atMediaCheckStack",
"[def @media] [attribute screen] ([property color]) { } [tag foo] { }");
MT("atMediaPropertyOnly",
"[def @media] ([property color]) { } [tag foo] { }");
MT("atMediaCheckStackInvalidAttribute",
"[def @media] [attribute&error foobarhello] { [tag foo] { } }");
MT("atMediaCheckStackInvalidAttribute",
"[def @media] [attribute&error foobarhello] { } [tag foo] { }");
@@ -53,6 +59,10 @@
MT("atMediaUnknownProperty",
"[def @media] [attribute screen] [operator and] ([property&error foobarhello]) { }");
// Make sure nesting works with media queries
MT("atMediaMaxWidthNested",
"[def @media] [attribute screen] [operator and] ([property max-width][operator :] [number 25px]) { [tag foo] { } }");
MT("tagSelector",
"[tag foo] { }");
@@ -108,6 +118,9 @@
MT("tagTwoProperties",
"[tag foo] { [property margin][operator :] [number 0]; [property padding][operator :] [number 0]; }");
MT("tagTwoPropertiesURL",
"[tag foo] { [property background][operator :] [string-2 url]([string //example.com/foo.png]); [property padding][operator :] [number 0]; }");
MT("commentSGML",
"[comment <!--comment-->]");
})();

0
applications/admin/static/codemirror/mode/d/d.js vendored Executable file → Normal file
View File

41
applications/admin/static/codemirror/mode/d/index.html vendored Executable file → Normal file
View File

@@ -1,18 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: D mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="d.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border: 2px inset #dee;}</style>
</head>
<body>
<h1>CodeMirror: D mode</h1>
<title>CodeMirror: D 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="../../addon/edit/matchbrackets.js"></script>
<script src="d.js"></script>
<style>.CodeMirror {border: 2px inset #dee;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">D</a>
</ul>
</div>
<article>
<h2>D mode</h2>
<form><textarea id="code" name="code">
/* D demo code // copied from phobos/sd/metastrings.d */
// Written in the D programming language.
@@ -258,5 +270,4 @@ deprecated alias parseUinteger ParseInteger;
<p><strong>MIME types defined:</strong> <code>text/x-d</code>
.</p>
</body>
</html>
</article>

View File

@@ -1,23 +1,36 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Diff mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="diff.js"></script>
<style>
<title>CodeMirror: Diff 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="diff.js"></script>
<style>
.CodeMirror {border-top: 1px solid #ddd; border-bottom: 1px solid #ddd;}
span.cm-meta {color: #a0b !important;}
span.cm-error { background-color: black; opacity: 0.4;}
span.cm-error.cm-string { background-color: red; }
span.cm-error.cm-tag { background-color: #2b2; }
</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Diff mode</h1>
<form><textarea id="code" name="code">
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Diff</a>
</ul>
</div>
<article>
<h2>Diff mode</h2>
<form><textarea id="code" name="code">
diff --git a/index.html b/index.html
index c1d9156..7764744 100644
--- a/index.html
@@ -101,5 +114,4 @@ index 04646a9..9a39cc7 100644
<p><strong>MIME types defined:</strong> <code>text/x-diff</code>.</p>
</body>
</html>
</article>

View File

@@ -1,16 +1,30 @@
<!doctype html>
<html>
<head>
<title>CodeMirror: ECL mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="ecl.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border: 1px solid black;}</style>
</head>
<body>
<h1>CodeMirror: ECL mode</h1>
<form><textarea id="code" name="code">
<!doctype html>
<title>CodeMirror: ECL 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="ecl.js"></script>
<style>.CodeMirror {border: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">ECL</a>
</ul>
</div>
<article>
<h2>ECL mode</h2>
<form><textarea id="code" name="code">
/*
sample useless code to demonstrate ecl syntax highlighting
this is a multiline comment!
@@ -35,5 +49,4 @@ output(d);
<p>Based on CodeMirror's clike mode. For more information see <a href="http://hpccsystems.com">HPCC Systems</a> web site.</p>
<p><strong>MIME types defined:</strong> <code>text/x-ecl</code>.</p>
</body>
</html>
</article>

View File

@@ -11,22 +11,15 @@ CodeMirror.defineMIME("text/x-erlang", "erlang");
CodeMirror.defineMode("erlang", function(cmCfg) {
function rval(state,stream,type) {
function rval(state,_stream,type) {
// distinguish between "." as terminator and record field operator
if (type == "record") {
state.context = "record";
}else{
state.context = false;
}
state.in_record = (type == "record");
// remember last significant bit on last line for indenting
if (type != "whitespace" && type != "comment") {
state.lastToken = stream.current();
}
// erlang -> CodeMirror tag
switch (type) {
case "atom": return "atom";
case "attribute": return "attribute";
case "boolean": return "special";
case "builtin": return "builtin";
case "comment": return "comment";
case "fun": return "meta";
@@ -55,6 +48,7 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
"after","begin","catch","case","cond","end","fun","if",
"let","of","query","receive","try","when"];
var separatorRE = /[\->\.,:;]/;
var separatorWords = [
"->",";",":",".",","];
@@ -62,12 +56,15 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
"and","andalso","band","bnot","bor","bsl","bsr","bxor",
"div","not","or","orelse","rem","xor"];
var symbolRE = /[\+\-\*\/<>=\|:!]/;
var symbolWords = [
"+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-"];
"+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-","!"];
var openParenRE = /[<\(\[\{]/;
var openParenWords = [
"<<","(","[","{"];
var closeParenRE = /[>\)\]\}]/;
var closeParenWords = [
"}","]",")",">>"];
@@ -102,53 +99,39 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
"term_to_binary","time","throw","tl","trunc","tuple_size",
"tuple_to_list","unlink","unregister","whereis"];
// ignored for indenting purposes
var ignoreWords = [
",", ":", "catch", "after", "of", "cond", "let", "query"];
var smallRE = /[a-z_]/;
var largeRE = /[A-Z_]/;
var digitRE = /[0-9]/;
var octitRE = /[0-7]/;
var anumRE = /[a-z_A-Z0-9]/;
var symbolRE = /[\+\-\*\/<>=\|:]/;
var openParenRE = /[<\(\[\{]/;
var closeParenRE = /[>\)\]\}]/;
var sepRE = /[\->\.,:;]/;
function isMember(element,list) {
return (-1 < list.indexOf(element));
}
function isPrev(stream,string) {
var start = stream.start;
var len = string.length;
if (len <= start) {
var word = stream.string.slice(start-len,start);
return word == string;
}else{
return false;
}
}
// [Ø-Þ] [À-Ö]
// [ß-ö] [ø-ÿ]
var anumRE = /[\w@Ø-ÞÀ-Öß-öø-ÿ]/;
var escapesRE =
/[0-7]{1,3}|[bdefnrstv\\"']|\^[a-zA-Z]|x[0-9a-zA-Z]{2}|x{[0-9a-zA-Z]+}/;
function tokenize(stream, state) {
// in multi-line string
if (state.in_string) {
state.in_string = (!doubleQuote(stream));
return rval(state,stream,"string");
}
// in multi-line atom
if (state.in_atom) {
state.in_atom = (!singleQuote(stream));
return rval(state,stream,"atom");
}
// whitespace
if (stream.eatSpace()) {
return rval(state,stream,"whitespace");
}
// attributes and type specs
if ((peekToken(state).token == "" || peekToken(state).token == ".") &&
stream.peek() == '-') {
stream.next();
if (stream.eat(smallRE) && stream.eatWhile(anumRE)) {
if (isMember(stream.current(),typeWords)) {
return rval(state,stream,"type");
}else{
return rval(state,stream,"attribute");
}
if ((peekToken(state).token == "") &&
stream.match(/-\s*[a-zß-öø-ÿ][\wØ-ÞÀ-Öß-öø-ÿ]*/)) {
if (isMember(stream.current(),typeWords)) {
return rval(state,stream,"type");
}else{
return rval(state,stream,"attribute");
}
stream.backUp(1);
}
var ch = stream.next();
@@ -166,57 +149,54 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
}
// record
if ( ch == "#") {
if (ch == "#") {
stream.eatWhile(anumRE);
return rval(state,stream,"record");
}
// char
if ( ch == "$") {
if (stream.next() == "\\") {
if (!stream.eatWhile(octitRE)) {
stream.next();
}
// dollar escape
if ( ch == "$" ) {
if (stream.next() == "\\" && !stream.match(escapesRE)) {
return rval(state,stream,"error");
}
return rval(state,stream,"string");
return rval(state,stream,"number");
}
// quoted atom
if (ch == '\'') {
if (singleQuote(stream)) {
return rval(state,stream,"atom");
}else{
return rval(state,stream,"error");
if (!(state.in_atom = (!singleQuote(stream)))) {
if (stream.match(/\s*\/\s*[0-9]/,false)) {
stream.match(/\s*\/\s*[0-9]/,true);
popToken(state);
return rval(state,stream,"fun"); // 'f'/0 style fun
}
if (stream.match(/\s*\(/,false) || stream.match(/\s*:/,false)) {
return rval(state,stream,"function");
}
}
return rval(state,stream,"atom");
}
// string
if (ch == '"') {
if (doubleQuote(stream)) {
return rval(state,stream,"string");
}else{
return rval(state,stream,"error");
}
state.in_string = (!doubleQuote(stream));
return rval(state,stream,"string");
}
// variable
if (largeRE.test(ch)) {
if (/[A-Z_Ø-ÞÀ-Ö]/.test(ch)) {
stream.eatWhile(anumRE);
return rval(state,stream,"variable");
}
// atom/keyword/BIF/function
if (smallRE.test(ch)) {
if (/[a-z_ß-öø-ÿ]/.test(ch)) {
stream.eatWhile(anumRE);
if (stream.peek() == "/") {
stream.next();
if (stream.eatWhile(digitRE)) {
return rval(state,stream,"fun"); // f/0 style fun
}else{
stream.backUp(1);
return rval(state,stream,"atom");
}
if (stream.match(/\s*\/\s*[0-9]/,false)) {
stream.match(/\s*\/\s*[0-9]/,true);
popToken(state);
return rval(state,stream,"fun"); // f/0 style fun
}
var w = stream.current();
@@ -224,37 +204,38 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
if (isMember(w,keywordWords)) {
pushToken(state,stream);
return rval(state,stream,"keyword");
}
if (stream.peek() == "(") {
}else if (stream.match(/\s*\(/,false)) {
// 'put' and 'erlang:put' are bifs, 'foo:put' is not
if (isMember(w,bifWords) &&
(!isPrev(stream,":") || isPrev(stream,"erlang:"))) {
return rval(state,stream,"builtin");
}else if (isMember(w,guardWords)) {
return rval(state,stream,"guard");
}else{
return rval(state,stream,"function");
}
}
if (isMember(w,guardWords)) {
return rval(state,stream,"guard");
}
if (isMember(w,operatorWords)) {
}else if (isMember(w,operatorWords)) {
return rval(state,stream,"operator");
}
if (stream.peek() == ":") {
}else if (stream.match(/\s*:/,false)) {
if (w == "erlang") {
return rval(state,stream,"builtin");
} else {
return rval(state,stream,"function");
}
}else if (isMember(w,["true","false"])) {
return rval(state,stream,"boolean");
}else{
return rval(state,stream,"atom");
}
return rval(state,stream,"atom");
}
// number
var digitRE = /[0-9]/;
var radixRE = /[0-9a-zA-Z]/; // 36#zZ style int
if (digitRE.test(ch)) {
stream.eatWhile(digitRE);
if (stream.eat('#')) {
stream.eatWhile(digitRE); // 16#10 style integer
stream.eatWhile(radixRE); // 36#aZ style integer
} else {
if (stream.eat('.')) { // float
stream.eatWhile(digitRE);
@@ -280,9 +261,9 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
}
// separators
if (greedy(stream,sepRE,separatorWords)) {
if (greedy(stream,separatorRE,separatorWords)) {
// distinguish between "." as terminator and record field operator
if (state.context == false) {
if (!state.in_record) {
pushToken(state,stream);
}
return rval(state,stream,"separator");
@@ -296,6 +277,17 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
return rval(state,stream,null);
}
function isPrev(stream,string) {
var start = stream.start;
var len = string.length;
if (len <= start) {
var word = stream.string.slice(start-len,start);
return word == string;
}else{
return false;
}
}
function nongreedy(stream,re,words) {
if (stream.current().length == 1 && re.test(stream.current())) {
stream.backUp(1);
@@ -347,31 +339,37 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
return false;
}
function Token(stream) {
this.token = stream ? stream.current() : "";
this.column = stream ? stream.column() : 0;
this.indent = stream ? stream.indentation() : 0;
function isMember(element,list) {
return (-1 < list.indexOf(element));
}
/////////////////////////////////////////////////////////////////////////////
function myIndent(state,textAfter) {
var indent = cmCfg.indentUnit;
var outdentWords = ["after","catch"];
var token = (peekToken(state)).token;
var wordAfter = takewhile(textAfter,/[^a-z]/);
if (isMember(token,openParenWords)) {
return (peekToken(state)).column+token.length;
}else if (token == "." || token == ""){
if (state.in_string || state.in_atom) {
return CodeMirror.Pass;
}else if (token == "") {
return 0;
}else if (isMember(token,openParenWords)) {
return (peekToken(state)).column+token.length;
}else if (token == "when") {
return (peekToken(state)).column+token.length+1;
}else if (token == "fun" && wordAfter == "") {
return (peekToken(state)).column+token.length;
}else if (token == "->") {
if (wordAfter == "end") {
if (isMember(wordAfter,["end","after","catch"])) {
return peekToken(state,2).column;
}else if (peekToken(state,2).token == "fun") {
return peekToken(state,2).column+indent;
}else if (peekToken(state,2).token == "") {
return indent;
}else{
return (peekToken(state)).indent+indent;
}
}else if (isMember(wordAfter,outdentWords)) {
}else if (isMember(wordAfter,["after","catch","of"])) {
return (peekToken(state)).indent;
}else{
return (peekToken(state)).column+indent;
@@ -383,6 +381,12 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
return m ? str.slice(0,m.index) : str;
}
function Token(stream) {
this.token = stream ? stream.current() : "";
this.column = stream ? stream.column() : 0;
this.indent = stream ? stream.indentation() : 0;
}
function popToken(state) {
return state.tokenStack.pop();
}
@@ -400,7 +404,13 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
function pushToken(state,stream) {
var token = stream.current();
var prev_token = peekToken(state).token;
if (isMember(token,ignoreWords)) {
if (token == ".") {
state.tokenStack = [];
return false;
}else if(isMember(token,[",", ":", "of", "cond", "let", "query"])) {
return false;
}else if (drop_last(prev_token,token)) {
return false;
}else if (drop_both(prev_token,token)) {
popToken(state);
@@ -408,18 +418,25 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
}else if (drop_first(prev_token,token)) {
popToken(state);
return pushToken(state,stream);
}else if (isMember(token,["after","catch"])) {
return false;
}else{
state.tokenStack.push(new Token(stream));
return true;
}
}
function drop_last(open, close) {
switch(open+" "+close) {
case "when ;": return true;
default: return false;
}
}
function drop_first(open, close) {
switch (open+" "+close) {
case "when ->": return true;
case "-> end": return true;
case "-> .": return true;
case ". .": return true;
default: return false;
}
}
@@ -436,6 +453,8 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
case "if end": return true;
case "receive end": return true;
case "try end": return true;
case "-> catch": return true;
case "-> after": return true;
case "-> ;": return true;
default: return false;
}
@@ -445,8 +464,9 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
startState:
function() {
return {tokenStack: [],
context: false,
lastToken: null};
in_record: false,
in_string: false,
in_atom: false};
},
token:

View File

@@ -1,19 +1,31 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Erlang mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="erlang.js"></script>
<link rel="stylesheet" href="../../theme/erlang-dark.css">
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Erlang mode</h1>
<title>CodeMirror: Erlang mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/erlang-dark.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="erlang.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"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Erlang</a>
</ul>
</div>
<article>
<h2>Erlang mode</h2>
<form><textarea id="code" name="code">
%% -*- mode: erlang; erlang-indent-level: 2 -*-
%%% Created : 7 May 2012 by mats cronqvist <masse@klarna.com>
@@ -32,7 +44,7 @@
rec_info(demo) -> record_info(fields,demo).
demo() -> expand_recs(?MODULE,#demo{a="A",b="BB"}).
expand_recs(M,List) when is_list(List) ->
[expand_recs(M,L)||L<-List];
expand_recs(M,Tup) when is_tuple(Tup) ->
@@ -60,5 +72,4 @@ expand_recs(_,Term) ->
</script>
<p><strong>MIME types defined:</strong> <code>text/x-erlang</code>.</p>
</body>
</html>
</article>

View File

@@ -1,18 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Gas mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="gas.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border: 2px inset #dee;}</style>
</head>
<body>
<h1>CodeMirror: Gas mode</h1>
<form>
<title>CodeMirror: Gas 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="gas.js"></script>
<style>.CodeMirror {border: 2px inset #dee;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Gas</a>
</ul>
</div>
<article>
<h2>Gas mode</h2>
<form>
<textarea id="code" name="code">
.syntax unified
.global main
@@ -53,5 +65,4 @@ message:
directives for the supplied architecture.
<p><strong>MIME types defined:</strong> <code>text/x-gas</code></p>
</body>
</html>
</article>

View File

@@ -1,27 +1,36 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: GFM mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/mode/overlay.js"></script>
<script src="../xml/xml.js"></script>
<script src="../markdown/markdown.js"></script>
<script src="gfm.js"></script>
<!-- Code block highlighting modes -->
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="../clike/clike.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: GFM mode</h1>
<title>CodeMirror: GFM 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="../../addon/mode/overlay.js"></script>
<script src="../xml/xml.js"></script>
<script src="../markdown/markdown.js"></script>
<script src="gfm.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="../clike/clike.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"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">GFM</a>
</ul>
</div>
<article>
<h2>GFM mode</h2>
<form><textarea id="code" name="code">
GitHub Flavored Markdown
========================
@@ -70,5 +79,4 @@ See http://github.github.com/github-flavored-markdown/.
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#gfm_*">normal</a>, <a href="../../test/index.html#verbose,gfm_*">verbose</a>.</p>
</body>
</html>
</article>

View File

@@ -1,19 +1,31 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Go mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/elegant.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="go.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border:1px solid #999; background:#ffc}</style>
</head>
<body>
<h1>CodeMirror: Go mode</h1>
<title>CodeMirror: Go mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/elegant.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="go.js"></script>
<style>.CodeMirror {border:1px solid #999; background:#ffc}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Go</a>
</ul>
</div>
<article>
<h2>Go mode</h2>
<form><textarea id="code" name="code">
// Prime Sieve in Go.
// Taken from the Go specification.
@@ -70,5 +82,4 @@ func main() {
</script>
<p><strong>MIME type:</strong> <code>text/x-go</code></p>
</body>
</html>
</article>

View File

@@ -203,7 +203,8 @@ CodeMirror.defineMode("groovy", function(config) {
else return ctx.indented + (closing ? 0 : config.indentUnit);
},
electricChars: "{}"
electricChars: "{}",
fold: "brace"
};
});

View File

@@ -1,18 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Groovy mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="groovy.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border-top: 1px solid #500; border-bottom: 1px solid #500;}</style>
</head>
<body>
<h1>CodeMirror: Groovy mode</h1>
<title>CodeMirror: Groovy 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="../../addon/edit/matchbrackets.js"></script>
<script src="groovy.js"></script>
<style>.CodeMirror {border-top: 1px solid #500; border-bottom: 1px solid #500;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Groovy</a>
</ul>
</div>
<article>
<h2>Groovy mode</h2>
<form><textarea id="code" name="code">
//Pattern for groovy script
def p = ~/.*\.groovy/
@@ -69,5 +81,4 @@ def change(currency, amount) {
</script>
<p><strong>MIME types defined:</strong> <code>text/x-groovy</code></p>
</body>
</html>
</article>

View File

@@ -1,21 +1,34 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: HAML mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../xml/xml.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../ruby/ruby.js"></script>
<script src="haml.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: HAML mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: HAML 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="../xml/xml.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../ruby/ruby.js"></script>
<script src="haml.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">HAML</a>
</ul>
</div>
<article>
<h2>HAML mode</h2>
<form><textarea id="code" name="code">
!!!
#content
.left.column(title="title"){:href => "/hello", :test => "#{hello}_#{world}"}
@@ -63,5 +76,4 @@
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#haml_*">normal</a>, <a href="../../test/index.html#verbose,haml_*">verbose</a>.</p>
</body>
</html>
</article>

View File

@@ -1,4 +1,4 @@
CodeMirror.defineMode("haskell", function() {
CodeMirror.defineMode("haskell", function(_config, modeConfig) {
function switchState(source, setState, f) {
setState(f);
@@ -221,6 +221,10 @@ CodeMirror.defineMode("haskell", function() {
"unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip",
"zip3", "zipWith", "zipWith3");
var override = modeConfig.overrideKeywords;
if (override) for (var word in override) if (override.hasOwnProperty(word))
wkw[word] = override[word];
return wkw;
})();

View File

@@ -1,19 +1,31 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Haskell mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="haskell.js"></script>
<link rel="stylesheet" href="../../theme/elegant.css">
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Haskell mode</h1>
<title>CodeMirror: Haskell mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/elegant.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="haskell.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"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Haskell</a>
</ul>
</div>
<article>
<h2>Haskell mode</h2>
<form><textarea id="code" name="code">
module UniquePerms (
uniquePerms
@@ -58,5 +70,4 @@ permBag bs = concatMap (\(f,cs) -> map (f:) $ permBag cs) . oneOfEach $ bs
</script>
<p><strong>MIME types defined:</strong> <code>text/x-haskell</code>.</p>
</body>
</html>
</article>

View File

@@ -297,7 +297,7 @@ CodeMirror.defineMode("haxe", function(config, parserConfig) {
function metadef(type) {
if(type == ":") return cont(metadef);
if(type == "variable") return cont(metadef);
if(type == "(") return cont(pushlex(")"), comasep(metaargs, ")"), poplex, statement);
if(type == "(") return cont(pushlex(")"), commasep(metaargs, ")"), poplex, statement);
}
function metaargs(type) {
if(type == "variable") return cont();

View File

@@ -1,16 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Haxe mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="haxe.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
</head>
<body>
<h1>CodeMirror: Haxe mode</h1>
<title>CodeMirror: Haxe 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="haxe.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"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Haxe</a>
</ul>
</div>
<article>
<h2>Haxe mode</h2>
<div><textarea id="code" name="code">
import one.two.Three;
@@ -86,5 +100,4 @@ enum Color
</script>
<p><strong>MIME types defined:</strong> <code>text/x-haxe</code>.</p>
</body>
</html>
</article>

View File

@@ -1,21 +1,33 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Html Embedded Scripts mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../xml/xml.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="htmlembedded.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Html Embedded Scripts mode</h1>
<title>CodeMirror: Html Embedded Scripts 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="../xml/xml.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="htmlembedded.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"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Html Embedded Scripts</a>
</ul>
</div>
<article>
<h2>Html Embedded Scripts mode</h2>
<form><textarea id="code" name="code">
<%
function hello(who) {
@@ -45,5 +57,4 @@ This is an example of EJS (embedded javascript)
<p><strong>MIME types defined:</strong> <code>application/x-aspx</code> (ASP.NET),
<code>application/x-ejs</code> (Embedded Javascript), <code>application/x-jsp</code> (JavaServer Pages)</p>
</body>
</html>
</article>

View File

@@ -1,21 +1,34 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: HTML mixed mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../xml/xml.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../vbscript/vbscript.js"></script>
<script src="htmlmixed.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
</head>
<body>
<h1>CodeMirror: HTML mixed mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: HTML mixed 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="../xml/xml.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../vbscript/vbscript.js"></script>
<script src="htmlmixed.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">HTML mixed</a>
</ul>
</div>
<article>
<h2>HTML mixed mode</h2>
<form><textarea id="code" name="code">
<html style="color: green">
<!-- this is a comment -->
<head>
@@ -69,5 +82,4 @@
(redefined, only takes effect if you load this parser after the
XML parser).</p>
</body>
</html>
</article>

View File

@@ -1,16 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: HTTP mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="http.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
</head>
<body>
<h1>CodeMirror: HTTP mode</h1>
<title>CodeMirror: HTTP 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="http.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"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">HTTP</a>
</ul>
</div>
<article>
<h2>HTTP mode</h2>
<div><textarea id="code" name="code">
POST /somewhere HTTP/1.1
@@ -28,5 +42,4 @@ This is the request body!
</script>
<p><strong>MIME types defined:</strong> <code>message/http</code>.</p>
</body>
</html>
</article>

View File

@@ -1,19 +1,33 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: JavaScript mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="../../addon/edit/continuecomment.js"></script>
<script src="../../addon/comment/comment.js"></script>
<script src="javascript.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
</head>
<body>
<h1>CodeMirror: JavaScript mode</h1>
<title>CodeMirror: JavaScript 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="../../addon/edit/matchbrackets.js"></script>
<script src="../../addon/comment/continuecomment.js"></script>
<script src="../../addon/comment/comment.js"></script>
<script src="javascript.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"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">JavaScript</a>
</ul>
</div>
<article>
<h2>JavaScript mode</h2>
<div><textarea id="code" name="code">
// Demo code (the actual new parser character stream implementation)
@@ -90,5 +104,4 @@ StringStream.prototype = {
</p>
<p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>, <code>text/typescript</code>, <code>application/typescript</code>.</p>
</body>
</html>
</article>

View File

@@ -78,18 +78,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
type = tp; content = cont;
return style;
}
function jsTokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'")
return chain(stream, state, jsTokenString(ch));
else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/))
return ret("number", "number");
else if (/[\[\]{}\(\),;\:\.]/.test(ch))
return ret(ch);
else if (ch == "0" && stream.eat(/x/i)) {
stream.eatWhile(/[\da-f]/i);
return ret("number", "number");
}
else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
return ret("number", "number");
}
@@ -258,17 +259,17 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "{") return cont(pushlex("}"), block, poplex);
if (type == ";") return cont();
if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse(cx.state.indented));
if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
if (type == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
poplex, statement, poplex);
poplex, statement, poplex);
if (type == "variable") return cont(pushlex("stat"), maybelabel);
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
block, poplex, poplex);
block, poplex, poplex);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
statement, poplex, popcontext);
statement, poplex, popcontext);
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
function expression(type) {
@@ -299,19 +300,20 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression);
return maybeoperatorNoComma(type, value, maybeoperatorComma);
return maybeoperatorNoComma(type, value, false);
}
function maybeoperatorNoComma(type, value, me) {
if (!me) me = maybeoperatorNoComma;
function maybeoperatorNoComma(type, value, noComma) {
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
var expr = noComma == false ? expression : expressionNoComma;
if (type == "operator") {
if (/\+\+|--/.test(value)) return cont(me);
if (value == "?") return cont(expression, expect(":"), expression);
return cont(expression);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
}
if (type == ";") return;
if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);
if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
}
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
@@ -373,14 +375,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "=") return cont(expressionNoComma, vardef2);
if (type == ",") return cont(vardef1);
}
function maybeelse(indent) {
return function(type, value) {
if (type == "keyword b" && value == "else") {
cx.state.lexical = new JSLexical(indent, 0, "form", null, cx.state.lexical);
return cont(statement, poplex);
}
return pass();
};
function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
}
function forspec1(type) {
if (type == "var") return cont(vardef1, expect(";"), forspec2);
@@ -441,6 +437,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
if (state.tokenize != jsTokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
// Kludge to prevent 'maybelse' from blocking lexical scope pops
for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i];
if (c == poplex) lexical = lexical.prev;
else if (c != maybeelse || /^else\b/.test(textAfter)) break;
}
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
lexical = lexical.prev;
@@ -461,7 +463,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
lineComment: jsonMode ? null : "//",
fold: "brace",
helperType: jsonMode ? "json" : "javascript",
jsonMode: jsonMode
};
});

View File

@@ -1,16 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: TypeScript mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="javascript.js"></script>
<link rel="stylesheet" href="../../doc/docs.css">
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
</head>
<body>
<h1>CodeMirror: TypeScript mode</h1>
<title>CodeMirror: TypeScript 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="javascript.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"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">TypeScript</a>
</ul>
</div>
<article>
<h2>TypeScript mode</h2>
<div><textarea id="code" name="code">
class Greeter {
@@ -44,5 +58,4 @@ document.body.appendChild(button)
</script>
<p>This is a specialization of the <a href="index.html">JavaScript mode</a>.</p>
</body>
</html>
</article>

View File

@@ -1,17 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Jinja2 mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="jinja2.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Jinja2 mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: Jinja2 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="jinja2.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"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Jinja2</a>
</ul>
</div>
<article>
<h2>Jinja2 mode</h2>
<form><textarea id="code" name="code">
&lt;html style="color: green"&gt;
&lt;!-- this is a comment --&gt;
&lt;head&gt;
@@ -34,5 +47,4 @@
CodeMirror.fromTextArea(document.getElementById("code"), {mode:
{name: "jinja2", htmlMode: true}});
</script>
</body>
</html>
</article>

View File

@@ -1,19 +1,32 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: LESS mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="less.js"></script>
<style>.CodeMirror {background: #f8f8f8; border: 1px solid #ddd; font-size:12px; height: 400px}</style>
<link rel="stylesheet" href="../../doc/docs.css">
<link rel="stylesheet" href="../../theme/lesser-dark.css">
</head>
<body>
<h1>CodeMirror: LESS mode</h1>
<form><textarea id="code" name="code">@media screen and (device-aspect-ratio: 16/9) { … }
<title>CodeMirror: LESS mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/lesser-dark.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="less.js"></script>
<style>.CodeMirror {background: #f8f8f8; border: 1px solid #ddd; font-size:12px; height: 400px}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">LESS</a>
</ul>
</div>
<article>
<h2>LESS mode</h2>
<form><textarea id="code" name="code">@media screen and (device-aspect-ratio: 16/9) { … }
@media screen and (device-aspect-ratio: 32/18) { … }
@media screen and (device-aspect-ratio: 1280/720) { … }
@media screen and (device-aspect-ratio: 2560/1440) { … }
@@ -737,5 +750,4 @@ td {
</script>
<p><strong>MIME types defined:</strong> <code>text/x-less</code>, <code>text/css</code> (if not previously defined).</p>
</body>
</html>
</article>

View File

@@ -1,7 +1,8 @@
/*
LESS mode - http://www.lesscss.org/
Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues GitHub: @peterkroon
Report bugs/issues here: https://github.com/marijnh/CodeMirror/issues
GitHub: @peterkroon
*/
CodeMirror.defineMode("less", function(config) {
@@ -17,68 +18,60 @@ CodeMirror.defineMode("less", function(config) {
else if (ch == "/" && stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
else if (ch == "<" && stream.eat("!")) {
} else if (ch == "<" && stream.eat("!")) {
state.tokenize = tokenSGMLComment;
return tokenSGMLComment(stream, state);
}
else if (ch == "=") ret(null, "compare");
} else if (ch == "=") ret(null, "compare");
else if (ch == "|" && stream.eat("=")) return ret(null, "compare");
else if (ch == "\"" || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
else if (ch == "/") { // e.g.: .png will not be parsed as a class
} else if (ch == "/") { // e.g.: .png will not be parsed as a class
if(stream.eat("/")){
state.tokenize = tokenSComment;
return tokenSComment(stream, state);
}else{
if(type == "string" || type == "(")return ret("string", "string");
if(state.stack[state.stack.length-1] != undefined)return ret(null, ch);
} else {
if(type == "string" || type == "(") return ret("string", "string");
if(state.stack[state.stack.length-1] != undefined) return ret(null, ch);
stream.eatWhile(/[\a-zA-Z0-9\-_.\s]/);
if( /\/|\)|#/.test(stream.peek() || (stream.eatSpace() && stream.peek() == ")")) || stream.eol() )return ret("string", "string"); // let url(/images/logo.png) without quotes return as string
}
}
else if (ch == "!") {
} else if (ch == "!") {
stream.match(/^\s*\w*/);
return ret("keyword", "important");
}
else if (/\d/.test(ch)) {
} else if (/\d/.test(ch)) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
}
else if (/[,+<>*\/]/.test(ch)) {
} else if (/[,+<>*\/]/.test(ch)) {
if(stream.peek() == "=" || type == "a")return ret("string", "string");
if(ch === ",")return ret(null, ch);
return ret(null, "select-op");
}
else if (/[;{}:\[\]()~\|]/.test(ch)) {
} else if (/[;{}:\[\]()~\|]/.test(ch)) {
if(ch == ":"){
stream.eatWhile(/[a-z\\\-]/);
if( selectors.test(stream.current()) ){
return ret("tag", "tag");
}else if(stream.peek() == ":"){//::-webkit-search-decoration
} else if(stream.peek() == ":"){//::-webkit-search-decoration
stream.next();
stream.eatWhile(/[a-z\\\-]/);
if(stream.current().match(/\:\:\-(o|ms|moz|webkit)\-/))return ret("string", "string");
if( selectors.test(stream.current().substring(1)) )return ret("tag", "tag");
return ret(null, ch);
}else{
} else {
return ret(null, ch);
}
}else if(ch == "~"){
} else if(ch == "~"){
if(type == "r")return ret("string", "string");
}else{
} else {
return ret(null, ch);
}
}
else if (ch == ".") {
} else if (ch == ".") {
if(type == "(" || type == "string")return ret("string", "string"); // allow url(../image.png)
stream.eatWhile(/[\a-zA-Z0-9\-_]/);
if(stream.peek() == " ")stream.eatSpace();
if(stream.peek() == ")")return ret("number", "unit");//rgba(0,0,0,.25);
return ret("tag", "tag");
}
else if (ch == "#") {
} else if (ch == "#") {
//we don't eat white-space, we want the hex color and or id only
stream.eatWhile(/[A-Za-z0-9]/);
//check if there is a proper hex color length e.g. #eee || #eeeEEE
@@ -93,43 +86,41 @@ CodeMirror.defineMode("less", function(config) {
//#time { color: #aaa }
else if(stream.peek() == "}" )return ret("number", "unit");
//we have a valid hex color value, parse as id whenever an element/class is defined after the hex(id) value e.g. #eee aaa || #eee .aaa
else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag");
else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag");
//when a hex value is on the end of a line, parse as id
else if(stream.eol())return ret("atom", "tag");
else if(stream.eol())return ret("atom", "tag");
//default
else return ret("number", "unit");
}else{//when not a valid hexvalue in the current stream e.g. #footer
else return ret("number", "unit");
} else {//when not a valid hexvalue in the current stream e.g. #footer
stream.eatWhile(/[\w\\\-]/);
return ret("atom", "tag");
}
}else{//when not a valid hexvalue length
} else {//when not a valid hexvalue length
stream.eatWhile(/[\w\\\-]/);
return ret("atom", "tag");
}
}
else if (ch == "&") {
} else if (ch == "&") {
stream.eatWhile(/[\w\-]/);
return ret(null, ch);
}
else {
} else {
stream.eatWhile(/[\w\\\-_%.{]/);
if(type == "string"){
return ret("string", "string");
}else if(stream.current().match(/(^http$|^https$)/) != null){
} else if(stream.current().match(/(^http$|^https$)/) != null){
stream.eatWhile(/[\w\\\-_%.{:\/]/);
return ret("string", "string");
}else if(stream.peek() == "<" || stream.peek() == ">"){
} else if(stream.peek() == "<" || stream.peek() == ">" || stream.peek() == "+"){
return ret("tag", "tag");
}else if( /\(/.test(stream.peek()) ){
} else if( /\(/.test(stream.peek()) ){
return ret(null, ch);
}else if (stream.peek() == "/" && state.stack[state.stack.length-1] != undefined){ // url(dir/center/image.png)
} else if (stream.peek() == "/" && state.stack[state.stack.length-1] != undefined){ // url(dir/center/image.png)
return ret("string", "string");
}else if( stream.current().match(/\-\d|\-.\d/) ){ // match e.g.: -5px -0.4 etc... only colorize the minus sign
} else if( stream.current().match(/\-\d|\-.\d/) ){ // match e.g.: -5px -0.4 etc... only colorize the minus sign
//commment out these 2 comment if you want the minus sign to be parsed as null -500px
//stream.backUp(stream.current().length-1);
//return ret(null, ch); //console.log( stream.current() );
//return ret(null, ch);
return ret("number", "unit");
}else if( /\/|[\s\)]/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == "/")) && stream.current().indexOf(".") !== -1){
} else if( /\/|[\s\)]/.test(stream.peek() || stream.eol() || (stream.eatSpace() && stream.peek() == "/")) && stream.current().indexOf(".") !== -1){
if(stream.current().substring(stream.current().length-1,stream.current().length) == "{"){
stream.backUp(1);
return ret("tag", "tag");
@@ -137,14 +128,15 @@ CodeMirror.defineMode("less", function(config) {
stream.eatSpace();
if( /[{<>.a-zA-Z\/]/.test(stream.peek()) || stream.eol() )return ret("tag", "tag"); // e.g. button.icon-plus
return ret("string", "string"); // let url(/images/logo.png) without quotes return as string
}else if( stream.eol() || stream.peek() == "[" || stream.peek() == "#" || type == "tag" ){
} else if( stream.eol() || stream.peek() == "[" || stream.peek() == "#" || type == "tag" ){
if(stream.current().substring(stream.current().length-1,stream.current().length) == "{")stream.backUp(1);
return ret("tag", "tag");
}else if(type == "compare" || type == "a" || type == "("){
} else if(type == "compare" || type == "a" || type == "("){
return ret("string", "string");
}else if(type == "|" || stream.current() == "-" || type == "["){
} else if(type == "|" || stream.current() == "-" || type == "["){
if(type == "|" )return ret("tag", "tag");
return ret(null, ch);
}else if(stream.peek() == ":") {
} else if(stream.peek() == ":") {
stream.next();
var t_v = stream.peek() == ":" ? true : false;
if(!t_v){
@@ -156,11 +148,14 @@ CodeMirror.defineMode("less", function(config) {
stream.backUp(new_pos-(old_pos-1));
return ret("tag", "tag");
} else stream.backUp(new_pos-(old_pos-1));
}else{
} else {
stream.backUp(1);
}
if(t_v)return ret("tag", "tag"); else return ret("variable", "variable");
}else{
} else if(state.stack[state.stack.length-1] === "font-family"){
return ret(null, null);
} else {
if(state.stack[state.stack.length-1] === "{" || type === "select-op" || (state.stack[state.stack.length-1] === "rule" && type === ",") )return ret("tag", "tag");
return ret("variable", "variable");
}
}
@@ -238,12 +233,15 @@ CodeMirror.defineMode("less", function(config) {
}
else if (type == "}") state.stack.pop();
else if (type == "@media") state.stack.push("@media");
else if (context == "{" && type != "comment") state.stack.push("rule");
else if (stream.current() === "font-family") state.stack[state.stack.length-1] = "font-family";
else if (context == "{" && type != "comment" && type !== "tag") state.stack.push("rule");
else if (stream.peek() === ":" && stream.current().match(/@|#/) === null) style = type;
return style;
},
indent: function(state, textAfter) {
var n = state.stack.length;
if (/^\}/.test(textAfter))
n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
return state.baseIndent + n * indentUnit;

View File

@@ -1,23 +0,0 @@
The MIT License
Copyright (c) 2013 Kenneth Bentley
Modified from the CoffeeScript CodeMirror mode, Copyright (c) 2011 Jeff Pickhardt
Modified from the Python CodeMirror mode, Copyright (c) 2010 Timothy Farrell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,17 +1,31 @@
<!doctype html>
<html>
<head>
<title>CodeMirror: LiveScript mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="livescript.js"></script>
<style>.CodeMirror {font-size: 80%;border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
<link rel="stylesheet" href="../../theme/solarized.css">
</head>
<body>
<h1>CodeMirror: LiveScript mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: LiveScript mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/solarized.css">
<script src="../../lib/codemirror.js"></script>
<script src="livescript.js"></script>
<style>.CodeMirror {font-size: 80%;border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">LiveScript</a>
</ul>
</div>
<article>
<h2>LiveScript mode</h2>
<form><textarea id="code" name="code">
# LiveScript mode for CodeMirror
# The following script, prelude.ls, is used to
# demonstrate LiveScript mode for CodeMirror.
@@ -442,5 +456,4 @@ export prelude = out$
<p>The LiveScript mode was written by Kenneth Bentley (<a href="LICENSE">license</a>).</p>
</body>
</html>
</article>

View File

@@ -1,19 +1,32 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Lua mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="../../lib/codemirror.js"></script>
<script src="lua.js"></script>
<link rel="stylesheet" href="../../theme/neat.css">
<style>.CodeMirror {border: 1px solid black;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Lua mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: Lua mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/neat.css">
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="../../lib/codemirror.js"></script>
<script src="lua.js"></script>
<style>.CodeMirror {border: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Lua</a>
</ul>
</div>
<article>
<h2>Lua mode</h2>
<form><textarea id="code" name="code">
--[[
example useless code to show lua syntax highlighting
this is multiline comment
@@ -70,5 +83,4 @@ end
the <code>lua-special</code> style.</p>
<p><strong>MIME types defined:</strong> <code>text/x-lua</code>.</p>
</body>
</html>
</article>

View File

@@ -1,20 +1,36 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: Markdown mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/continuelist.js"></script>
<script src="../xml/xml.js"></script>
<script src="markdown.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Markdown mode</h1>
<!-- source: http://daringfireball.net/projects/markdown/basics.text -->
<title>CodeMirror: Markdown 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="../../addon/edit/continuelist.js"></script>
<script src="../xml/xml.js"></script>
<script src="markdown.js"></script>
<style type="text/css">
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
.cm-s-default .cm-trailing-space-a:before,
.cm-s-default .cm-trailing-space-b:before {position: absolute; content: "\00B7"; color: #777;}
.cm-s-default .cm-trailing-space-new-line:before {position: absolute; content: "\21B5"; color: #777;}
</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Markdown</a>
</ul>
</div>
<article>
<h2>Markdown mode</h2>
<form><textarea id="code" name="code">
Markdown: Basics
================
@@ -340,5 +356,4 @@ Output:
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#markdown_*">normal</a>, <a href="../../test/index.html#verbose,markdown_*">verbose</a>.</p>
</body>
</html>
</article>

View File

@@ -103,6 +103,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.f = inlineNormal;
state.block = blockNormal;
}
// Reset state.trailingSpace
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
// Mark this line as blank
state.thisLineHasContent = false;
return null;
@@ -217,6 +220,12 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
}
if (state.trailingSpaceNewLine) {
styles.push("trailing-space-new-line");
} else if (state.trailingSpace) {
styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
}
return styles.length ? styles.join(' ') : null;
}
@@ -369,6 +378,14 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
}
if (ch === ' ') {
if (stream.match(/ +$/, false)) {
state.trailingSpace++;
} else if (state.trailingSpace) {
state.trailingSpaceNewLine = true;
}
}
return getType(state);
}
@@ -453,7 +470,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
taskList: false,
list: false,
listDepth: 0,
quote: 0
quote: 0,
trailingSpace: 0,
trailingSpaceNewLine: false
};
},
@@ -481,6 +500,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
list: s.list,
listDepth: s.listDepth,
quote: s.quote,
trailingSpace: s.trailingSpace,
trailingSpaceNewLine: s.trailingSpaceNewLine,
md_inside: s.md_inside
};
},
@@ -504,6 +525,10 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
// Reset state.code
state.code = false;
// Reset state.trailingSpace
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
state.f = state.block;
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
var difference = Math.floor((indentation - state.indentation) / 4) * 4;

View File

@@ -5,6 +5,20 @@
MT("plainText",
"foo");
// Don't style single trailing space
MT("trailingSpace1",
"foo ");
// Two or more trailing spaces should be styled with line break character
MT("trailingSpace2",
"foo[trailing-space-a ][trailing-space-new-line ]");
MT("trailingSpace3",
"foo[trailing-space-a ][trailing-space-b ][trailing-space-new-line ]");
MT("trailingSpace4",
"foo[trailing-space-a ][trailing-space-b ][trailing-space-a ][trailing-space-new-line ]");
// Code blocks using 4 spaces (regardless of CodeMirror.tabSize value)
MT("codeBlocksUsing4Spaces",
" [comment foo]");

View File

@@ -13,12 +13,15 @@ CodeMirror.modeInfo = [
{name: 'CSS', mime: 'text/css', mode: 'css'},
{name: 'D', mime: 'text/x-d', mode: 'd'},
{name: 'diff', mime: 'text/x-diff', mode: 'diff'},
{name: 'DTD', mime: 'application/xml-dtd', mode: 'dtd'},
{name: 'ECL', mime: 'text/x-ecl', mode: 'ecl'},
{name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'},
{name: 'Fortran', mime: 'text/x-fortran', mode: 'fortran'},
{name: 'Gas', mime: 'text/x-gas', mode: 'gas'},
{name: 'GitHub Flavored Markdown', mode: 'gfm'},
{name: 'GitHub Flavored Markdown', mime: 'text/x-gfm', mode: 'gfm'},
{name: 'GO', mime: 'text/x-go', mode: 'go'},
{name: 'Groovy', mime: 'text/x-groovy', mode: 'groovy'},
{name: 'HAML', mime: 'text/x-haml', mode: 'haml'},
{name: 'Haskell', mime: 'text/x-haskell', mode: 'haskell'},
{name: 'Haxe', mime: 'text/x-haxe', mode: 'haxe'},
{name: 'ASP.NET', mime: 'application/x-aspx', mode: 'htmlembedded'},
@@ -26,6 +29,7 @@ CodeMirror.modeInfo = [
{name: 'JavaServer Pages', mime: 'application/x-jsp', mode: 'htmlembedded'},
{name: 'HTML', mime: 'text/html', mode: 'htmlmixed'},
{name: 'HTTP', mime: 'message/http', mode: 'http'},
{name: 'Jade', mime: 'text/x-jade', mode: 'jade'},
{name: 'JavaScript', mime: 'text/javascript', mode: 'javascript'},
{name: 'JSON', mime: 'application/x-json', mode: 'javascript'},
{name: 'JSON', mime: 'application/json', mode: 'javascript'},
@@ -36,16 +40,19 @@ CodeMirror.modeInfo = [
{name: 'Lua', mime: 'text/x-lua', mode: 'lua'},
{name: 'Markdown (GitHub-flavour)', mime: 'text/x-markdown', mode: 'markdown'},
{name: 'mIRC', mime: 'text/mirc', mode: 'mirc'},
{name: 'Nginx', mime: 'text/x-nginx-conf', mode: 'nginx'},
{name: 'NTriples', mime: 'text/n-triples', mode: 'ntriples'},
{name: 'OCaml', mime: 'text/x-ocaml', mode: 'ocaml'},
{name: 'Octave', mime: 'text/x-octave', mode: 'octave'},
{name: 'Pascal', mime: 'text/x-pascal', mode: 'pascal'},
{name: 'Perl', mime: 'text/x-perl', mode: 'perl'},
{name: 'PHP', mime: 'text/x-php', mode: 'php'},
{name: 'PHP(HTML)', mime: 'application/x-httpd-php', mode: 'php'},
{name: 'Pig', mime: 'text/x-pig', mode: 'pig'},
{name: 'Plain Text', mime: 'text/plain', mode: 'null'},
{name: 'Properties files', mime: 'text/x-properties', mode: 'clike'},
{name: 'Properties files', mime: 'text/x-properties', mode: 'properties'},
{name: 'Python', mime: 'text/x-python', mode: 'python'},
{name: 'Cython', mime: 'text/x-cython', mode: 'python'},
{name: 'R', mime: 'text/x-rsrc', mode: 'r'},
{name: 'reStructuredText', mime: 'text/x-rst', mode: 'rst'},
{name: 'Ruby', mime: 'text/x-ruby', mode: 'ruby'},
@@ -57,6 +64,7 @@ CodeMirror.modeInfo = [
{name: 'Sieve', mime: 'application/sieve', mode: 'sieve'},
{name: 'Smalltalk', mime: 'text/x-stsrc', mode: 'smalltalk'},
{name: 'Smarty', mime: 'text/x-smarty', mode: 'smarty'},
{name: 'SmartyMixed', mime: 'text/x-smarty', mode: 'smartymixed'},
{name: 'SPARQL', mime: 'application/x-sparql-query', mode: 'sparql'},
{name: 'SQL', mime: 'text/x-sql', mode: 'sql'},
{name: 'MariaDB', mime: 'text/x-mariadb', mode: 'sql'},
@@ -65,6 +73,8 @@ CodeMirror.modeInfo = [
{name: 'Tcl', mime: 'text/x-tcl', mode: 'tcl'},
{name: 'TiddlyWiki ', mime: 'text/x-tiddlywiki', mode: 'tiddlywiki'},
{name: 'Tiki wiki', mime: 'text/tiki', mode: 'tiki'},
{name: 'TOML', mime: 'text/x-toml', mode: 'toml'},
{name: 'Turtle', mime: 'text/turtle', mode: 'turtle'},
{name: 'VB.NET', mime: 'text/x-vb', mode: 'vb'},
{name: 'VBScript', mime: 'text/vbscript', mode: 'vbscript'},
{name: 'Velocity', mime: 'text/velocity', mode: 'velocity'},

View File

@@ -1,18 +1,31 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CodeMirror: mIRC mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="mirc.js"></script>
<link rel="stylesheet" href="../../theme/twilight.css">
<style>.CodeMirror {border: 1px solid black;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: mIRC mode</h1>
<form><textarea id="code" name="code">
<title>CodeMirror: mIRC mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../theme/twilight.css">
<script src="../../lib/codemirror.js"></script>
<script src="mirc.js"></script>
<style>.CodeMirror {border: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><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/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">mIRC</a>
</ul>
</div>
<article>
<h2>mIRC mode</h2>
<form><textarea id="code" name="code">
;AKA Nick Tracker by Ford_Lawnmower irc.GeekShed.net #Script-Help
;*****************************************************************************;
;**Start Setup
@@ -145,5 +158,4 @@ Raw 315:*: {
<p><strong>MIME types defined:</strong> <code>text/mirc</code>.</p>
</body>
</html>
</article>

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