3 changes: 3 additions & 0 deletions mode/pegjs/pegjs.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../javascript/javascript"));
Expand Down
5 changes: 5 additions & 0 deletions mode/perl/perl.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// CodeMirror2 mode/perl/perl.js (text/x-perl) beta 0.10 (2011-11-08)
// This is a part of CodeMirror from https://github.com/sabaca/CodeMirror_mode_perl (mail@sabaca.com)

Expand Down Expand Up @@ -788,6 +791,8 @@ CodeMirror.defineMode("perl",function(){
return (state.tokenize||tokenPerl)(stream,state);},
electricChars:"{}"};});

CodeMirror.registerHelper("wordChars", "perl", /[\\w$]/);

CodeMirror.defineMIME("text/x-perl", "perl");

// it's like "peek", but need for look-ahead or look-behind if index < 0
Expand Down
7 changes: 5 additions & 2 deletions mode/php/php.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
Expand Down Expand Up @@ -94,6 +97,7 @@
var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once";
CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
CodeMirror.registerHelper("wordChars", "php", /[\\w$]/);

var phpConfig = {
name: "clike",
Expand Down Expand Up @@ -183,8 +187,7 @@
state.curState = state.html;
return "meta";
} else {
var result = phpMode.token(stream, state.curState);
return (stream.pos <= stream.start) ? phpMode.token(stream, state.curState) : result;
return phpMode.token(stream, state.curState);
}
}

Expand Down
3 changes: 3 additions & 0 deletions mode/php/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "php");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
Expand Down
3 changes: 3 additions & 0 deletions mode/pig/pig.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/*
* Pig Latin Mode for CodeMirror 2
* @author Prasanth Jayachandran
Expand Down
3 changes: 3 additions & 0 deletions mode/properties/properties.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/puppet/puppet.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
612 changes: 284 additions & 328 deletions mode/python/python.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions mode/q/q.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/r/r.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/rpm/rpm.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/rst/rst.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../python/python"), require("../stex/stex"), require("../../addon/mode/overlay"));
Expand Down
3 changes: 3 additions & 0 deletions mode/ruby/ruby.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/ruby/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "ruby");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
Expand Down
3 changes: 3 additions & 0 deletions mode/rust/rust.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/sass/sass.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/scheme/scheme.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/**
* Author: Koh Zi Han, based on implementation by Koh Zi Chun
*/
Expand Down
11 changes: 9 additions & 2 deletions mode/shell/shell.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down Expand Up @@ -33,10 +36,15 @@ CodeMirror.defineMode('shell', function() {
'touch vi vim wall wc wget who write yes zsh');

function tokenBase(stream, state) {
if (stream.eatSpace()) return null;

var sol = stream.sol();
var ch = stream.next();

if (ch === '\\') {
stream.next();
return null;
}
if (ch === '\'' || ch === '"' || ch === '`') {
state.tokens.unshift(tokenString(ch));
return tokenize(stream, state);
Expand All @@ -63,7 +71,7 @@ CodeMirror.defineMode('shell', function() {
}
if (/\d/.test(ch)) {
stream.eatWhile(/\d/);
if(!/\w/.test(stream.peek())) {
if(stream.eol() || !/\w/.test(stream.peek())) {
return 'number';
}
}
Expand Down Expand Up @@ -119,7 +127,6 @@ CodeMirror.defineMode('shell', function() {
return {
startState: function() {return {tokens:[]};},
token: function(stream, state) {
if (stream.eatSpace()) return null;
return tokenize(stream, state);
}
};
Expand Down
58 changes: 58 additions & 0 deletions mode/shell/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({}, "shell");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }

MT("var",
"text [def $var] text");
MT("varBraces",
"text[def ${var}]text");
MT("varVar",
"text [def $a$b] text");
MT("varBracesVarBraces",
"text[def ${a}${b}]text");

MT("singleQuotedVar",
"[string 'text $var text']");
MT("singleQuotedVarBraces",
"[string 'text ${var} text']");

MT("doubleQuotedVar",
'[string "text ][def $var][string text"]');
MT("doubleQuotedVarBraces",
'[string "text][def ${var}][string text"]');
MT("doubleQuotedVarPunct",
'[string "text ][def $@][string text"]');
MT("doubleQuotedVarVar",
'[string "][def $a$b][string "]');
MT("doubleQuotedVarBracesVarBraces",
'[string "][def ${a}${b}][string "]');

MT("notAString",
"text\\'text");
MT("escapes",
"outside\\'\\\"\\`\\\\[string \"inside\\`\\'\\\"\\\\`\\$notAVar\"]outside\\$\\(notASubShell\\)");

MT("subshell",
"[builtin echo] [quote $(whoami)] s log, stardate [quote `date`].");
MT("doubleQuotedSubshell",
"[builtin echo] [string \"][quote $(whoami)][string 's log, stardate `date`.\"]");

MT("hashbang",
"[meta #!/bin/bash]");
MT("comment",
"text [comment # Blurb]");

MT("numbers",
"[number 0] [number 1] [number 2]");
MT("keywords",
"[keyword while] [atom true]; [keyword do]",
" [builtin sleep] [number 3]",
"[keyword done]");
MT("options",
"[builtin ls] [attribute -l] [attribute --human-readable]");
MT("operator",
"[def var][operator =]value");
})();
3 changes: 3 additions & 0 deletions mode/sieve/sieve.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/smalltalk/smalltalk.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/smarty/smarty.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/**
* Smarty 2 and 3 mode.
*/
Expand Down
3 changes: 3 additions & 0 deletions mode/smartymixed/smartymixed.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/**
* @file smartymixed.js
* @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML)
Expand Down
3 changes: 3 additions & 0 deletions mode/solr/solr.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/sparql/sparql.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/sql/sql.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/stex/stex.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/*
* Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de)
* Licence: MIT
Expand Down
3 changes: 3 additions & 0 deletions mode/stex/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({tabSize: 4}, "stex");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
Expand Down
3 changes: 3 additions & 0 deletions mode/tcl/tcl.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

//tcl mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara

(function(mod) {
Expand Down
3 changes: 3 additions & 0 deletions mode/tiddlywiki/tiddlywiki.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/***
|''Name''|tiddlywiki.js|
|''Description''|Enables TiddlyWikiy syntax highlighting using CodeMirror|
Expand Down
3 changes: 3 additions & 0 deletions mode/tiki/tiki.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/toml/toml.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/turtle/turtle.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/vb/vb.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/vbscript/vbscript.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

/*
For extra ASP classic objects, initialize CodeMirror instance with this option:
isASP: true
Expand Down
3 changes: 3 additions & 0 deletions mode/velocity/velocity.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/verilog/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({indentUnit: 4}, "verilog");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
Expand Down
3 changes: 3 additions & 0 deletions mode/verilog/verilog.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/xml/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml";
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), mname); }
Expand Down
5 changes: 4 additions & 1 deletion mode/xml/xml.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down Expand Up @@ -121,7 +124,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
state.state = baseState;
state.tagName = state.tagStart = null;
var next = state.tokenize(stream, state);
return next ? next + " error" : "error";
return next ? next + " tag error" : "tag error";
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
Expand Down
3 changes: 3 additions & 0 deletions mode/xquery/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Don't take these too seriously -- the expected results appear to be
// based on the results of actual runs without any serious manual
// verification. If a change you made causes them to fail, the test is
Expand Down
3 changes: 3 additions & 0 deletions mode/xquery/xquery.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/yaml/yaml.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
3 changes: 3 additions & 0 deletions mode/z80/z80.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codemirror",
"version":"4.1.0",
"version":"4.2.0",
"main": "lib/codemirror.js",
"description": "In-browser code editing made bearable",
"licenses": [{"type": "MIT",
Expand Down
8 changes: 4 additions & 4 deletions test/emacs_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@

sim("openLine", "foo bar", "Alt-F", "Ctrl-O", txt("foo\n bar"))

sim("transposeChar", "abcd\n\ne",
"Ctrl-F", "Ctrl-T", "Ctrl-T", txt("bcad\n\ne"), at(0, 3),
"Ctrl-F", "Ctrl-T", "Ctrl-T", "Ctrl-T", txt("bcda\n\ne"), at(0, 4),
"Ctrl-F", "Ctrl-T", txt("bcd\na\ne"), at(1, 1));
sim("transposeChar", "abcd\ne",
"Ctrl-F", "Ctrl-T", "Ctrl-T", txt("bcad\ne"), at(0, 3),
"Ctrl-F", "Ctrl-T", "Ctrl-T", "Ctrl-T", txt("bcda\ne"), at(0, 4),
"Ctrl-F", "Ctrl-T", txt("bcde\na"), at(1, 0));

sim("manipWordCase", "foo BAR bAZ",
"Alt-C", "Alt-L", "Alt-U", txt("Foo bar BAZ"),
Expand Down
2 changes: 2 additions & 0 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ <h2>Test Suite</h2>
<script src="../mode/markdown/test.js"></script>
<script src="../mode/gfm/gfm.js"></script>
<script src="../mode/gfm/test.js"></script>
<script src="../mode/shell/shell.js"></script>
<script src="../mode/shell/test.js"></script>
<script src="../mode/stex/stex.js"></script>
<script src="../mode/stex/test.js"></script>
<script src="../mode/verilog/verilog.js"></script>
Expand Down
7 changes: 6 additions & 1 deletion test/lint/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ var scopePasser = walk.make({
ScopeBody: function(node, prev, c) { c(node, node.scope); }
});

var cBlob = /^\/\/ CodeMirror, copyright \(c\) by Marijn Haverbeke and others\n\/\/ Distributed under an MIT license: http:\/\/codemirror.net\/LICENSE\n\n/;

function checkFile(fileName) {
var file = fs.readFileSync(fileName, "utf8"), notAllowed;
if (notAllowed = file.match(/[\x00-\x08\x0b\x0c\x0e-\x19\uFEFF\t]|[ \t]\n/)) {
Expand All @@ -41,6 +43,9 @@ function checkFile(fileName) {
var info = acorn.getLineInfo(file, notAllowed.index);
fail(msg + " at line " + info.line + ", column " + info.column, {source: fileName});
}

if (!cBlob.test(file))
fail("Missing license blob", {source: fileName});

var globalsSeen = Object.create(null);

Expand Down Expand Up @@ -152,7 +157,7 @@ function checkDir(dir) {
fs.readdirSync(dir).forEach(function(file) {
var fname = dir + "/" + file;
if (/\.js$/.test(file)) checkFile(fname);
else if (file != "dep" && fs.lstatSync(fname).isDirectory()) checkDir(fname);
else if (fs.lstatSync(fname).isDirectory()) checkDir(fname);
});
}

Expand Down
13 changes: 13 additions & 0 deletions test/mode_test.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,16 @@
.mt-output .mt-style {
font-size: x-small;
}

.mt-output .mt-state {
font-size: x-small;
vertical-align: top;
}

.mt-output .mt-state-row {
display: none;
}

.mt-state-unhide .mt-output .mt-state-row {
display: table-row;
}
62 changes: 42 additions & 20 deletions test/mode_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
pos = end;
}
text = text.replace(/\[\[|\]\]/g, function(s) {return s.charAt(0);});
tokens.push(style, text);
tokens.push({style: style, text: text});
plain += text;
}
}
Expand All @@ -67,16 +67,17 @@
};

function esc(str) {
return str.replace('&', '&amp;').replace('<', '&lt;');
return str.replace('&', '&amp;').replace('<', '&lt;').replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
;
}

function compare(text, expected, mode) {

var expectedOutput = [];
for (var i = 0; i < expected.length; i += 2) {
var sty = expected[i];
for (var i = 0; i < expected.length; ++i) {
var sty = expected[i].style;
if (sty && sty.indexOf(" ")) sty = sty.split(' ').sort().join(' ');
expectedOutput.push(sty, expected[i + 1]);
expectedOutput.push({style: sty, text: expected[i].text});
}

var observedOutput = highlight(text, mode);
Expand All @@ -89,7 +90,7 @@
s += '<div class="cm-s-default">';
s += 'expected:';
s += prettyPrintOutputTable(expectedOutput, diff);
s += 'observed:';
s += 'observed: [<a onclick="this.parentElement.className+=\' mt-state-unhide\'">display states</a>]';
s += prettyPrintOutputTable(observedOutput, diff);
s += '</div>';
s += '</div>';
Expand All @@ -101,8 +102,21 @@
if (s) throw new Failure(s);
}

function stringify(obj) {
function replacer(key, obj) {
if (typeof obj == "function") {
var m = obj.toString().match(/function\s*[^\s(]*/);
return m ? m[0] : "function";
}
return obj;
}
if (window.JSON && JSON.stringify)
return JSON.stringify(obj, replacer, 2);
return "[unsupported]"; // Fail safely if no native JSON.
}

function highlight(string, mode) {
var state = mode.startState()
var state = mode.startState();

var lines = string.replace(/\r\n/g,'\n').split('\n');
var st = [], pos = 0;
Expand All @@ -119,19 +133,21 @@
if (line == "" && mode.blankLine) mode.blankLine(state);
/* Start copied code from CodeMirror.highlight */
while (!stream.eol()) {
var compare = mode.token(stream, state), substr = stream.current();
if (stream.start >= stream.pos)
for (var j = 0; j < 10 && stream.start >= stream.pos; j++)
var compare = mode.token(stream, state);
if (j == 10)
throw new Failure("Failed to advance the stream." + stream.string + " " + stream.pos);
var substr = stream.current();
if (compare && compare.indexOf(" ") > -1) compare = compare.split(' ').sort().join(' ');
stream.start = stream.pos;
if (pos && st[pos-2] == compare && !newLine) {
st[pos-1] += substr;
if (pos && st[pos-1].style == compare && !newLine) {
st[pos-1].text += substr;
} else if (substr) {
st[pos++] = compare; st[pos++] = substr;
st[pos++] = {style: compare, text: substr, state: stringify(state)};
}
// Give up when line is ridiculously long
if (stream.pos > 5000) {
st[pos++] = null; st[pos++] = this.text.slice(stream.pos);
st[pos++] = {style: null, text: this.text.slice(stream.pos)};
break;
}
newLine = false;
Expand All @@ -144,27 +160,33 @@
function highlightOutputsDifferent(o1, o2) {
var minLen = Math.min(o1.length, o2.length);
for (var i = 0; i < minLen; ++i)
if (o1[i] != o2[i]) return i >> 1;
if (o1[i].style != o2[i].style || o1[i].text != o2[i].text) return i;
if (o1.length > minLen || o2.length > minLen) return minLen;
}

function prettyPrintOutputTable(output, diffAt) {
var s = '<table class="mt-output">';
s += '<tr>';
for (var i = 0; i < output.length; i += 2) {
var style = output[i], val = output[i+1];
for (var i = 0; i < output.length; ++i) {
var style = output[i].style, val = output[i].text;
s +=
'<td class="mt-token"' + (i == diffAt * 2 ? " style='background: pink'" : "") + '>' +
'<span class="cm-' + esc(String(style)) + '">' +
esc(val.replace(/ /g,'\xb7')) +
esc(val.replace(/ /g,'\xb7')) + // · MIDDLE DOT
'</span>' +
'</td>';
}
s += '</tr><tr>';
for (var i = 0; i < output.length; i += 2) {
s += '<td class="mt-style"><span>' + (output[i] || null) + '</span></td>';
for (var i = 0; i < output.length; ++i) {
s += '<td class="mt-style"><span>' + (output[i].style || null) + '</span></td>';
}
if(output[0].state) {
s += '</tr><tr class="mt-state-row" title="State AFTER each token">';
for (var i = 0; i < output.length; ++i) {
s += '<td class="mt-state"><pre>' + esc(output[i].state) + '</pre></td>';
}
}
s += '</table>';
s += '</tr></table>';
return s;
}
})();
6 changes: 6 additions & 0 deletions test/sublime_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@
1, 0, 2, 0,
2, 2, 2, 2));

stTest("swapLineEmptyBottomSel", "1\n2\n3",
setSel(0, 1, 1, 0),
"swapLineDown", val("2\n1\n3"), hasSel(1, 1, 2, 0),
"swapLineUp", val("1\n2\n3"), hasSel(0, 1, 1, 0),
"swapLineUp", val("1\n2\n3"), hasSel(0, 0, 0, 0));

stTest("swapLineUpFromEnd", "a\nb\nc",
Pos(2, 1), "swapLineUp",
hasSel(1, 1, 1, 1), val("a\nc\nb"));
Expand Down
13 changes: 13 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,19 @@ testCM("atomicMarker", function(cm) {
eq(cm.getValue().length, 53, "del chunk");
});

testCM("selectionBias", function(cm) {
cm.markText(Pos(0, 1), Pos(0, 3), {atomic: true});
cm.setCursor(Pos(0, 2));
eqPos(cm.getCursor(), Pos(0, 3));
cm.setCursor(Pos(0, 2));
eqPos(cm.getCursor(), Pos(0, 1));
cm.setCursor(Pos(0, 2), null, {bias: -1});
eqPos(cm.getCursor(), Pos(0, 1));
cm.setCursor(Pos(0, 4));
cm.setCursor(Pos(0, 2), null, {bias: 1});
eqPos(cm.getCursor(), Pos(0, 3), "A");
}, {value: "12345"});

testCM("readOnlyMarker", function(cm) {
function mark(ll, cl, lr, cr, at) {
return cm.markText(Pos(ll, cl), Pos(lr, cr),
Expand Down
55 changes: 53 additions & 2 deletions test/vim_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function copyCursor(cur) {

function forEach(arr, func) {
for (var i = 0; i < arr.length; i++) {
func(arr[i]);
func(arr[i], i, arr);
}
}

Expand Down Expand Up @@ -1141,6 +1141,13 @@ testVim('a_eol', function(cm, vim, helpers) {
helpers.assertCursorAt(0, lines[0].length);
eq('vim-insert', cm.getOption('keyMap'));
});
testVim('a_endOfSelectedArea', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('v', 'j', 'l');
helpers.doKeys('A');
helpers.assertCursorAt(1, 2);
eq('vim-insert', cm.getOption('keyMap'));
}, {value: 'foo\nbar'});
testVim('i', function(cm, vim, helpers) {
cm.setCursor(0, 1);
helpers.doKeys('i');
Expand Down Expand Up @@ -1620,7 +1627,50 @@ testVim('o_visual', function(cm,vim,helpers) {
helpers.doKeys('d');
eq('p',cm.getValue());
}, { value: 'abcd\nefgh\nijkl\nmnop'});
testVim('uppercase/lowercase_visual', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('v', 'l', 'l');
helpers.doKeys('U');
helpers.assertCursorAt(0, 0);
helpers.doKeys('v', 'l', 'l');
helpers.doKeys('u');
helpers.assertCursorAt(0, 0);
helpers.doKeys('l', 'l', 'l', '.');
helpers.assertCursorAt(0, 3);
cm.setCursor(0, 0);
helpers.doKeys('q', 'a', 'v', 'j', 'U', 'q');
helpers.assertCursorAt(0, 0);
helpers.doKeys('j', '@', 'a');
helpers.assertCursorAt(1, 0);
cm.setCursor(3, 0);
helpers.doKeys('V', 'U', 'j', '.');
eq('ABCDEF\nGHIJKL\nMnopq\nSHORT LINE\nLONG LINE OF TEXT', cm.getValue());
}, { value: 'abcdef\nghijkl\nmnopq\nshort line\nlong line of text'});
testVim('visual_paste', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('v', 'l', 'l', 'y', 'j', 'v', 'l', 'p');
helpers.assertCursorAt(1, 4);
eq('this is a\nunthi test for visual paste', cm.getValue());
cm.setCursor(0, 0);
// in case of pasting whole line
helpers.doKeys('y', 'y');
cm.setCursor(1, 6);
helpers.doKeys('v', 'l', 'l', 'l', 'p');
helpers.assertCursorAt(2, 0);
eq('this is a\nunthi \nthis is a\n for visual paste', cm.getValue());
}, { value: 'this is a\nunit test for visual paste'});

// This checks the contents of the register used to paste the text
testVim('v_paste_from_register', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('"', 'a', 'y', 'w');
cm.setCursor(1, 0);
helpers.doKeys('v', 'p');
cm.openDialog = helpers.fakeOpenDialog('registers');
cm.openNotification = helpers.fakeOpenNotification(function(text) {
is(/a\s+register/.test(text));
});
}, { value: 'register contents\nare not erased'});
testVim('S_normal', function(cm, vim, helpers) {
cm.setCursor(0, 1);
helpers.doKeys('j', 'S');
Expand Down Expand Up @@ -2325,7 +2375,8 @@ testVim('HML', function(cm, vim, helpers) {
return upper + lower;
})()});

var zVals = ['zb','zz','zt','z-','z.','z<CR>'].map(function(e, idx){
var zVals = [];
forEach(['zb','zz','zt','z-','z.','z<CR>'], function(e, idx){
var lineNum = 250;
var lines = 35;
testVim(e, function(cm, vim, helpers) {
Expand Down
40 changes: 40 additions & 0 deletions theme/neo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* neo theme for codemirror */

/* Color scheme */

.cm-s-neo.CodeMirror {
background-color:#ffffff;
color:#2e383c;
line-height:1.4375;
}
.cm-s-neo .cm-comment {color:#75787b}
.cm-s-neo .cm-keyword, .cm-s-neo .cm-property {color:#1d75b3}
.cm-s-neo .cm-atom,.cm-s-neo .cm-number {color:#75438a}
.cm-s-neo .cm-node,.cm-s-neo .cm-tag {color:#9c3328}
.cm-s-neo .cm-string {color:#b35e14}
.cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier {color:#047d65}


/* Editor styling */

.cm-s-neo pre {
padding:0;
}

.cm-s-neo .CodeMirror-gutters {
border:none;
border-right:10px solid transparent;
background-color:transparent;
}

.cm-s-neo .CodeMirror-linenumber {
padding:0;
color:#e0e2e5;
}

.cm-s-neo div.CodeMirror-cursor {
width: auto;
border: 0;
background: rgba(155,157,162,0.37);
z-index: 1;
}