2014-01-24 13:03:04 -08:00
// Edited by Nick to remove some browser-specific stuff and make more things identifiers, not support constants.
ace . define ( 'ace/mode/javascript' , [ 'require' , 'exports' , 'module' , 'ace/lib/oop' , 'ace/mode/text' , 'ace/tokenizer' , 'ace/mode/javascript_highlight_rules' , 'ace/mode/matching_brace_outdent' , 'ace/range' , 'ace/worker/worker_client' , 'ace/mode/behaviour/cstyle' , 'ace/mode/folding/cstyle' ] , function ( require , exports , module ) {
var oop = require ( "../lib/oop" ) ;
var TextMode = require ( "./text" ) . Mode ;
var Tokenizer = require ( "../tokenizer" ) . Tokenizer ;
var JavaScriptHighlightRules = require ( "./javascript_highlight_rules" ) . JavaScriptHighlightRules ;
var MatchingBraceOutdent = require ( "./matching_brace_outdent" ) . MatchingBraceOutdent ;
var Range = require ( "../range" ) . Range ;
var WorkerClient = require ( "../worker/worker_client" ) . WorkerClient ;
var CstyleBehaviour = require ( "./behaviour/cstyle" ) . CstyleBehaviour ;
var CStyleFoldMode = require ( "./folding/cstyle" ) . FoldMode ;
var Mode = function ( ) {
this . HighlightRules = JavaScriptHighlightRules ;
this . $outdent = new MatchingBraceOutdent ( ) ;
this . $behaviour = new CstyleBehaviour ( ) ;
this . foldingRules = new CStyleFoldMode ( ) ;
} ;
oop . inherits ( Mode , TextMode ) ;
( function ( ) {
this . lineCommentStart = "//" ;
this . blockComment = { start : "/*" , end : "*/" } ;
this . getNextLineIndent = function ( state , line , tab ) {
var indent = this . $getIndent ( line ) ;
var tokenizedLine = this . getTokenizer ( ) . getLineTokens ( line , state ) ;
var tokens = tokenizedLine . tokens ;
var endState = tokenizedLine . state ;
if ( tokens . length && tokens [ tokens . length - 1 ] . type == "comment" ) {
return indent ;
}
if ( state == "start" || state == "no_regex" ) {
var match = line . match ( /^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/ ) ;
if ( match ) {
indent += tab ;
}
} else if ( state == "doc-start" ) {
if ( endState == "start" || endState == "no_regex" ) {
return "" ;
}
var match = line . match ( /^\s*(\/?)\*/ ) ;
if ( match ) {
if ( match [ 1 ] ) {
indent += " " ;
}
indent += "* " ;
}
}
return indent ;
} ;
this . checkOutdent = function ( state , line , input ) {
return this . $outdent . checkOutdent ( line , input ) ;
} ;
this . autoOutdent = function ( state , doc , row ) {
this . $outdent . autoOutdent ( doc , row ) ;
} ;
this . createWorker = function ( session ) {
var worker = new WorkerClient ( [ "ace" ] , "ace/mode/javascript_worker" , "JavaScriptWorker" ) ;
worker . attachToDocument ( session . getDocument ( ) ) ;
worker . on ( "jslint" , function ( results ) {
session . setAnnotations ( results . data ) ;
} ) ;
worker . on ( "terminate" , function ( ) {
session . clearAnnotations ( ) ;
} ) ;
return worker ;
} ;
this . $id = "ace/mode/javascript" ;
} ) . call ( Mode . prototype ) ;
exports . Mode = Mode ;
} ) ;
ace . define ( 'ace/mode/javascript_highlight_rules' , [ 'require' , 'exports' , 'module' , 'ace/lib/oop' , 'ace/mode/doc_comment_highlight_rules' , 'ace/mode/text_highlight_rules' ] , function ( require , exports , module ) {
var oop = require ( "../lib/oop" ) ;
var DocCommentHighlightRules = require ( "./doc_comment_highlight_rules" ) . DocCommentHighlightRules ;
var TextHighlightRules = require ( "./text_highlight_rules" ) . TextHighlightRules ;
var JavaScriptHighlightRules = function ( ) {
var keywordMapper = this . createKeywordMapper ( {
"variable.language" :
"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|" + // Constructors
"Namespace|QName|XML|XMLList|" + // E4X
"ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" +
"Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|" +
"Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + // Errors
"SyntaxError|TypeError|URIError|" +
"decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions
"isNaN|parseFloat|parseInt|" +
"JSON|Math|" + // Other
"this|arguments|prototype" , // Pseudo
"keyword" :
"const|yield|import|get|set|" +
"break|case|catch|continue|default|delete|do|else|finally|for|function|" +
"if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" +
"__parent__|__count__|escape|unescape|with|__proto__|" +
"class|enum|extends|super|export|implements|private|public|interface|package|protected|static" ,
"storage.type" :
"const|let|var|function" ,
"constant.language" :
"null|Infinity|NaN|undefined" ,
"support.function" :
"alert" ,
"constant.language.boolean" : "true|false"
} , "identifier" ) ;
var kwBeforeRe = "case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void" ;
var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b" ;
var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex
"u[0-9a-fA-F]{4}|" + // unicode
"[0-2][0-7]{0,2}|" + // oct
"3[0-6][0-7]?|" + // oct
"37[0-7]?|" + // oct
"[4-7][0-7]?|" + //oct
".)" ;
this . $rules = {
"no_regex" : [
{
token : "comment" ,
regex : "\\/\\/" ,
next : "line_comment"
} ,
DocCommentHighlightRules . getStartRule ( "doc-start" ) ,
{
token : "comment" , // multi line comment
regex : /\/\*/ ,
next : "comment"
} , {
token : "string" ,
regex : "'(?=.)" ,
next : "qstring"
} , {
token : "string" ,
regex : '"(?=.)' ,
next : "qqstring"
} , {
token : "constant.numeric" , // hex
regex : /0[xX][0-9a-fA-F]+\b/
} , {
token : "constant.numeric" , // float
regex : /[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/
} , {
token : [
"storage.type" , "punctuation.operator" , "support.function" ,
"punctuation.operator" , "entity.name.function" , "text" , "keyword.operator"
] ,
regex : "(" + identifierRe + ")(\\.)(prototype)(\\.)(" + identifierRe + ")(\\s*)(=)" ,
next : "function_arguments"
} , {
token : [
"storage.type" , "punctuation.operator" , "entity.name.function" , "text" ,
"keyword.operator" , "text" , "storage.type" , "text" , "paren.lparen"
] ,
regex : "(" + identifierRe + ")(\\.)(" + identifierRe + ")(\\s*)(=)(\\s*)(function)(\\s*)(\\()" ,
next : "function_arguments"
} , {
token : [
"entity.name.function" , "text" , "keyword.operator" , "text" , "storage.type" ,
"text" , "paren.lparen"
] ,
regex : "(" + identifierRe + ")(\\s*)(=)(\\s*)(function)(\\s*)(\\()" ,
next : "function_arguments"
} , {
token : [
"storage.type" , "punctuation.operator" , "entity.name.function" , "text" ,
"keyword.operator" , "text" ,
"storage.type" , "text" , "entity.name.function" , "text" , "paren.lparen"
] ,
regex : "(" + identifierRe + ")(\\.)(" + identifierRe + ")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()" ,
next : "function_arguments"
} , {
token : [
"storage.type" , "text" , "entity.name.function" , "text" , "paren.lparen"
] ,
regex : "(function)(\\s+)(" + identifierRe + ")(\\s*)(\\()" ,
next : "function_arguments"
} , {
token : [
"entity.name.function" , "text" , "punctuation.operator" ,
"text" , "storage.type" , "text" , "paren.lparen"
] ,
regex : "(" + identifierRe + ")(\\s*)(:)(\\s*)(function)(\\s*)(\\()" ,
next : "function_arguments"
} , {
token : [
"text" , "text" , "storage.type" , "text" , "paren.lparen"
] ,
regex : "(:)(\\s*)(function)(\\s*)(\\()" ,
next : "function_arguments"
} , {
token : "keyword" ,
regex : "(?:" + kwBeforeRe + ")\\b" ,
next : "start"
} , {
token : keywordMapper ,
regex : identifierRe
} , {
token : "keyword.operator" ,
regex : /--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/ ,
next : "start"
} , {
token : "punctuation.operator" ,
regex : /\?|\:|\,|\;|\./ ,
next : "start"
} , {
token : "paren.lparen" ,
regex : /[\[({]/ ,
next : "start"
} , {
token : "paren.rparen" ,
regex : /[\])}]/
} , {
token : "keyword.operator" ,
regex : /\/=?/ ,
next : "start"
} , {
token : "comment" ,
regex : /^#!.*$/
}
] ,
"start" : [
DocCommentHighlightRules . getStartRule ( "doc-start" ) ,
{
token : "comment" , // multi line comment
regex : "\\/\\*" ,
next : "comment_regex_allowed"
} , {
token : "comment" ,
regex : "\\/\\/" ,
next : "line_comment_regex_allowed"
} , {
token : "string.regexp" ,
regex : "\\/" ,
next : "regex"
} , {
token : "text" ,
regex : "\\s+|^$" ,
next : "start"
} , {
token : "empty" ,
regex : "" ,
next : "no_regex"
}
] ,
"regex" : [
{
token : "regexp.keyword.operator" ,
regex : "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"
} , {
token : "string.regexp" ,
regex : "/[sxngimy]*" ,
next : "no_regex"
} , {
token : "invalid" ,
regex : /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/
} , {
token : "constant.language.escape" ,
regex : /\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/
} , {
token : "constant.language.delimiter" ,
regex : /\|/
} , {
token : "constant.language.escape" ,
regex : /\[\^?/ ,
next : "regex_character_class"
} , {
token : "empty" ,
regex : "$" ,
next : "no_regex"
} , {
defaultToken : "string.regexp"
}
] ,
"regex_character_class" : [
{
token : "regexp.keyword.operator" ,
regex : "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"
} , {
token : "constant.language.escape" ,
regex : "]" ,
next : "regex"
} , {
token : "constant.language.escape" ,
regex : "-"
} , {
token : "empty" ,
regex : "$" ,
next : "no_regex"
} , {
defaultToken : "string.regexp.charachterclass"
}
] ,
"function_arguments" : [
{
token : "variable.parameter" ,
regex : identifierRe
} , {
token : "punctuation.operator" ,
regex : "[, ]+"
} , {
token : "punctuation.operator" ,
regex : "$"
} , {
token : "empty" ,
regex : "" ,
next : "no_regex"
}
] ,
"comment_regex_allowed" : [
{ token : "comment" , regex : "\\*\\/" , next : "start" } ,
{ defaultToken : "comment" }
] ,
"comment" : [
{ token : "comment" , regex : "\\*\\/" , next : "no_regex" } ,
{ defaultToken : "comment" }
] ,
"line_comment_regex_allowed" : [
{ token : "comment" , regex : "$|^" , next : "start" } ,
{ defaultToken : "comment" }
] ,
"line_comment" : [
{ token : "comment" , regex : "$|^" , next : "no_regex" } ,
{ defaultToken : "comment" }
] ,
"qqstring" : [
{
token : "constant.language.escape" ,
regex : escapedRe
} , {
token : "string" ,
regex : "\\\\$" ,
next : "qqstring"
} , {
token : "string" ,
regex : '"|$' ,
next : "no_regex"
} , {
defaultToken : "string"
}
] ,
"qstring" : [
{
token : "constant.language.escape" ,
regex : escapedRe
} , {
token : "string" ,
regex : "\\\\$" ,
next : "qstring"
} , {
token : "string" ,
regex : "'|$" ,
next : "no_regex"
} , {
defaultToken : "string"
}
]
} ;
this . embedRules ( DocCommentHighlightRules , "doc-" ,
[ DocCommentHighlightRules . getEndRule ( "no_regex" ) ] ) ;
} ;
oop . inherits ( JavaScriptHighlightRules , TextHighlightRules ) ;
exports . JavaScriptHighlightRules = JavaScriptHighlightRules ;
} ) ;
ace . define ( 'ace/mode/doc_comment_highlight_rules' , [ 'require' , 'exports' , 'module' , 'ace/lib/oop' , 'ace/mode/text_highlight_rules' ] , function ( require , exports , module ) {
var oop = require ( "../lib/oop" ) ;
var TextHighlightRules = require ( "./text_highlight_rules" ) . TextHighlightRules ;
var DocCommentHighlightRules = function ( ) {
this . $rules = {
"start" : [ {
token : "comment.doc.tag" ,
regex : "@[\\w\\d_]+" // TODO: fix email addresses
} , {
token : "comment.doc.tag" ,
regex : "\\bTODO\\b"
} , {
defaultToken : "comment.doc"
} ]
} ;
} ;
oop . inherits ( DocCommentHighlightRules , TextHighlightRules ) ;
DocCommentHighlightRules . getStartRule = function ( start ) {
return {
token : "comment.doc" , // doc comment
regex : "\\/\\*(?=\\*)" ,
next : start
} ;
} ;
DocCommentHighlightRules . getEndRule = function ( start ) {
return {
token : "comment.doc" , // closing comment
regex : "\\*\\/" ,
next : start
} ;
} ;
exports . DocCommentHighlightRules = DocCommentHighlightRules ;
} ) ;
ace . define ( 'ace/mode/matching_brace_outdent' , [ 'require' , 'exports' , 'module' , 'ace/range' ] , function ( require , exports , module ) {
var Range = require ( "../range" ) . Range ;
var MatchingBraceOutdent = function ( ) { } ;
( function ( ) {
this . checkOutdent = function ( line , input ) {
if ( ! /^\s+$/ . test ( line ) )
return false ;
return /^\s*\}/ . test ( input ) ;
} ;
this . autoOutdent = function ( doc , row ) {
var line = doc . getLine ( row ) ;
var match = line . match ( /^(\s*\})/ ) ;
if ( ! match ) return 0 ;
var column = match [ 1 ] . length ;
var openBracePos = doc . findMatchingBracket ( { row : row , column : column } ) ;
if ( ! openBracePos || openBracePos . row == row ) return 0 ;
var indent = this . $getIndent ( doc . getLine ( openBracePos . row ) ) ;
doc . replace ( new Range ( row , 0 , row , column - 1 ) , indent ) ;
} ;
this . $getIndent = function ( line ) {
return line . match ( /^\s*/ ) [ 0 ] ;
} ;
} ) . call ( MatchingBraceOutdent . prototype ) ;
exports . MatchingBraceOutdent = MatchingBraceOutdent ;
} ) ;
ace . define ( 'ace/mode/behaviour/cstyle' , [ 'require' , 'exports' , 'module' , 'ace/lib/oop' , 'ace/mode/behaviour' , 'ace/token_iterator' , 'ace/lib/lang' ] , function ( require , exports , module ) {
var oop = require ( "../../lib/oop" ) ;
var Behaviour = require ( "../behaviour" ) . Behaviour ;
var TokenIterator = require ( "../../token_iterator" ) . TokenIterator ;
var lang = require ( "../../lib/lang" ) ;
var SAFE _INSERT _IN _TOKENS =
[ "text" , "paren.rparen" , "punctuation.operator" ] ;
var SAFE _INSERT _BEFORE _TOKENS =
[ "text" , "paren.rparen" , "punctuation.operator" , "comment" ] ;
var autoInsertedBrackets = 0 ;
var autoInsertedRow = - 1 ;
var autoInsertedLineEnd = "" ;
var maybeInsertedBrackets = 0 ;
var maybeInsertedRow = - 1 ;
var maybeInsertedLineStart = "" ;
var maybeInsertedLineEnd = "" ;
var CstyleBehaviour = function ( ) {
CstyleBehaviour . isSaneInsertion = function ( editor , session ) {
var cursor = editor . getCursorPosition ( ) ;
var iterator = new TokenIterator ( session , cursor . row , cursor . column ) ;
if ( ! this . $matchTokenType ( iterator . getCurrentToken ( ) || "text" , SAFE _INSERT _IN _TOKENS ) ) {
var iterator2 = new TokenIterator ( session , cursor . row , cursor . column + 1 ) ;
if ( ! this . $matchTokenType ( iterator2 . getCurrentToken ( ) || "text" , SAFE _INSERT _IN _TOKENS ) )
return false ;
}
iterator . stepForward ( ) ;
return iterator . getCurrentTokenRow ( ) !== cursor . row ||
this . $matchTokenType ( iterator . getCurrentToken ( ) || "text" , SAFE _INSERT _BEFORE _TOKENS ) ;
} ;
CstyleBehaviour . $matchTokenType = function ( token , types ) {
return types . indexOf ( token . type || token ) > - 1 ;
} ;
CstyleBehaviour . recordAutoInsert = function ( editor , session , bracket ) {
var cursor = editor . getCursorPosition ( ) ;
var line = session . doc . getLine ( cursor . row ) ;
if ( ! this . isAutoInsertedClosing ( cursor , line , autoInsertedLineEnd [ 0 ] ) )
autoInsertedBrackets = 0 ;
autoInsertedRow = cursor . row ;
autoInsertedLineEnd = bracket + line . substr ( cursor . column ) ;
autoInsertedBrackets ++ ;
} ;
CstyleBehaviour . recordMaybeInsert = function ( editor , session , bracket ) {
var cursor = editor . getCursorPosition ( ) ;
var line = session . doc . getLine ( cursor . row ) ;
if ( ! this . isMaybeInsertedClosing ( cursor , line ) )
maybeInsertedBrackets = 0 ;
maybeInsertedRow = cursor . row ;
maybeInsertedLineStart = line . substr ( 0 , cursor . column ) + bracket ;
maybeInsertedLineEnd = line . substr ( cursor . column ) ;
maybeInsertedBrackets ++ ;
} ;
CstyleBehaviour . isAutoInsertedClosing = function ( cursor , line , bracket ) {
return autoInsertedBrackets > 0 &&
cursor . row === autoInsertedRow &&
bracket === autoInsertedLineEnd [ 0 ] &&
line . substr ( cursor . column ) === autoInsertedLineEnd ;
} ;
CstyleBehaviour . isMaybeInsertedClosing = function ( cursor , line ) {
return maybeInsertedBrackets > 0 &&
cursor . row === maybeInsertedRow &&
line . substr ( cursor . column ) === maybeInsertedLineEnd &&
line . substr ( 0 , cursor . column ) == maybeInsertedLineStart ;
} ;
CstyleBehaviour . popAutoInsertedClosing = function ( ) {
autoInsertedLineEnd = autoInsertedLineEnd . substr ( 1 ) ;
autoInsertedBrackets -- ;
} ;
CstyleBehaviour . clearMaybeInsertedClosing = function ( ) {
maybeInsertedBrackets = 0 ;
maybeInsertedRow = - 1 ;
} ;
this . add ( "braces" , "insertion" , function ( state , action , editor , session , text ) {
var cursor = editor . getCursorPosition ( ) ;
var line = session . doc . getLine ( cursor . row ) ;
if ( text == '{' ) {
var selection = editor . getSelectionRange ( ) ;
var selected = session . doc . getTextRange ( selection ) ;
if ( selected !== "" && selected !== "{" && editor . getWrapBehavioursEnabled ( ) ) {
return {
text : '{' + selected + '}' ,
selection : false
} ;
} else if ( CstyleBehaviour . isSaneInsertion ( editor , session ) ) {
if ( /[\]\}\)]/ . test ( line [ cursor . column ] ) || editor . inMultiSelectMode ) {
CstyleBehaviour . recordAutoInsert ( editor , session , "}" ) ;
return {
text : '{}' ,
selection : [ 1 , 1 ]
} ;
} else {
CstyleBehaviour . recordMaybeInsert ( editor , session , "{" ) ;
return {
text : '{' ,
selection : [ 1 , 1 ]
} ;
}
}
} else if ( text == '}' ) {
var rightChar = line . substring ( cursor . column , cursor . column + 1 ) ;
if ( rightChar == '}' ) {
var matching = session . $findOpeningBracket ( '}' , { column : cursor . column + 1 , row : cursor . row } ) ;
if ( matching !== null && CstyleBehaviour . isAutoInsertedClosing ( cursor , line , text ) ) {
CstyleBehaviour . popAutoInsertedClosing ( ) ;
return {
text : '' ,
selection : [ 1 , 1 ]
} ;
}
}
} else if ( text == "\n" || text == "\r\n" ) {
var closing = "" ;
if ( CstyleBehaviour . isMaybeInsertedClosing ( cursor , line ) ) {
closing = lang . stringRepeat ( "}" , maybeInsertedBrackets ) ;
CstyleBehaviour . clearMaybeInsertedClosing ( ) ;
}
var rightChar = line . substring ( cursor . column , cursor . column + 1 ) ;
if ( rightChar === '}' ) {
var openBracePos = session . findMatchingBracket ( { row : cursor . row , column : cursor . column + 1 } , '}' ) ;
if ( ! openBracePos )
return null ;
var next _indent = this . $getIndent ( session . getLine ( openBracePos . row ) ) ;
} else if ( closing ) {
var next _indent = this . $getIndent ( line ) ;
} else {
return ;
}
var indent = next _indent + session . getTabString ( ) ;
return {
text : '\n' + indent + '\n' + next _indent + closing ,
selection : [ 1 , indent . length , 1 , indent . length ]
} ;
} else {
CstyleBehaviour . clearMaybeInsertedClosing ( ) ;
}
} ) ;
this . add ( "braces" , "deletion" , function ( state , action , editor , session , range ) {
var selected = session . doc . getTextRange ( range ) ;
if ( ! range . isMultiLine ( ) && selected == '{' ) {
var line = session . doc . getLine ( range . start . row ) ;
var rightChar = line . substring ( range . end . column , range . end . column + 1 ) ;
if ( rightChar == '}' ) {
range . end . column ++ ;
return range ;
} else {
maybeInsertedBrackets -- ;
}
}
} ) ;
this . add ( "parens" , "insertion" , function ( state , action , editor , session , text ) {
if ( text == '(' ) {
var selection = editor . getSelectionRange ( ) ;
var selected = session . doc . getTextRange ( selection ) ;
if ( selected !== "" && editor . getWrapBehavioursEnabled ( ) ) {
return {
text : '(' + selected + ')' ,
selection : false
} ;
} else if ( CstyleBehaviour . isSaneInsertion ( editor , session ) ) {
CstyleBehaviour . recordAutoInsert ( editor , session , ")" ) ;
return {
text : '()' ,
selection : [ 1 , 1 ]
} ;
}
} else if ( text == ')' ) {
var cursor = editor . getCursorPosition ( ) ;
var line = session . doc . getLine ( cursor . row ) ;
var rightChar = line . substring ( cursor . column , cursor . column + 1 ) ;
if ( rightChar == ')' ) {
var matching = session . $findOpeningBracket ( ')' , { column : cursor . column + 1 , row : cursor . row } ) ;
if ( matching !== null && CstyleBehaviour . isAutoInsertedClosing ( cursor , line , text ) ) {
CstyleBehaviour . popAutoInsertedClosing ( ) ;
return {
text : '' ,
selection : [ 1 , 1 ]
} ;
}
}
}
} ) ;
this . add ( "parens" , "deletion" , function ( state , action , editor , session , range ) {
var selected = session . doc . getTextRange ( range ) ;
if ( ! range . isMultiLine ( ) && selected == '(' ) {
var line = session . doc . getLine ( range . start . row ) ;
var rightChar = line . substring ( range . start . column + 1 , range . start . column + 2 ) ;
if ( rightChar == ')' ) {
range . end . column ++ ;
return range ;
}
}
} ) ;
this . add ( "brackets" , "insertion" , function ( state , action , editor , session , text ) {
if ( text == '[' ) {
var selection = editor . getSelectionRange ( ) ;
var selected = session . doc . getTextRange ( selection ) ;
if ( selected !== "" && editor . getWrapBehavioursEnabled ( ) ) {
return {
text : '[' + selected + ']' ,
selection : false
} ;
} else if ( CstyleBehaviour . isSaneInsertion ( editor , session ) ) {
CstyleBehaviour . recordAutoInsert ( editor , session , "]" ) ;
return {
text : '[]' ,
selection : [ 1 , 1 ]
} ;
}
} else if ( text == ']' ) {
var cursor = editor . getCursorPosition ( ) ;
var line = session . doc . getLine ( cursor . row ) ;
var rightChar = line . substring ( cursor . column , cursor . column + 1 ) ;
if ( rightChar == ']' ) {
var matching = session . $findOpeningBracket ( ']' , { column : cursor . column + 1 , row : cursor . row } ) ;
if ( matching !== null && CstyleBehaviour . isAutoInsertedClosing ( cursor , line , text ) ) {
CstyleBehaviour . popAutoInsertedClosing ( ) ;
return {
text : '' ,
selection : [ 1 , 1 ]
} ;
}
}
}
} ) ;
this . add ( "brackets" , "deletion" , function ( state , action , editor , session , range ) {
var selected = session . doc . getTextRange ( range ) ;
if ( ! range . isMultiLine ( ) && selected == '[' ) {
var line = session . doc . getLine ( range . start . row ) ;
var rightChar = line . substring ( range . start . column + 1 , range . start . column + 2 ) ;
if ( rightChar == ']' ) {
range . end . column ++ ;
return range ;
}
}
} ) ;
this . add ( "string_dquotes" , "insertion" , function ( state , action , editor , session , text ) {
if ( text == '"' || text == "'" ) {
var quote = text ;
var selection = editor . getSelectionRange ( ) ;
var selected = session . doc . getTextRange ( selection ) ;
if ( selected !== "" && selected !== "'" && selected != '"' && editor . getWrapBehavioursEnabled ( ) ) {
return {
text : quote + selected + quote ,
selection : false
} ;
} else {
var cursor = editor . getCursorPosition ( ) ;
var line = session . doc . getLine ( cursor . row ) ;
var leftChar = line . substring ( cursor . column - 1 , cursor . column ) ;
if ( leftChar == '\\' ) {
return null ;
}
var tokens = session . getTokens ( selection . start . row ) ;
var col = 0 , token ;
var quotepos = - 1 ; // Track whether we're inside an open quote.
for ( var x = 0 ; x < tokens . length ; x ++ ) {
token = tokens [ x ] ;
if ( token . type == "string" ) {
quotepos = - 1 ;
} else if ( quotepos < 0 ) {
quotepos = token . value . indexOf ( quote ) ;
}
if ( ( token . value . length + col ) > selection . start . column ) {
break ;
}
col += tokens [ x ] . value . length ;
}
if ( ! token || ( quotepos < 0 && token . type !== "comment" && ( token . type !== "string" || ( ( selection . start . column !== token . value . length + col - 1 ) && token . value . lastIndexOf ( quote ) === token . value . length - 1 ) ) ) ) {
if ( ! CstyleBehaviour . isSaneInsertion ( editor , session ) )
return ;
return {
text : quote + quote ,
selection : [ 1 , 1 ]
} ;
} else if ( token && token . type === "string" ) {
var rightChar = line . substring ( cursor . column , cursor . column + 1 ) ;
if ( rightChar == quote ) {
return {
text : '' ,
selection : [ 1 , 1 ]
} ;
}
}
}
}
} ) ;
this . add ( "string_dquotes" , "deletion" , function ( state , action , editor , session , range ) {
var selected = session . doc . getTextRange ( range ) ;
if ( ! range . isMultiLine ( ) && ( selected == '"' || selected == "'" ) ) {
var line = session . doc . getLine ( range . start . row ) ;
var rightChar = line . substring ( range . start . column + 1 , range . start . column + 2 ) ;
if ( rightChar == selected ) {
range . end . column ++ ;
return range ;
}
}
} ) ;
} ;
oop . inherits ( CstyleBehaviour , Behaviour ) ;
exports . CstyleBehaviour = CstyleBehaviour ;
} ) ;
ace . define ( 'ace/mode/folding/cstyle' , [ 'require' , 'exports' , 'module' , 'ace/lib/oop' , 'ace/range' , 'ace/mode/folding/fold_mode' ] , function ( require , exports , module ) {
var oop = require ( "../../lib/oop" ) ;
var Range = require ( "../../range" ) . Range ;
var BaseFoldMode = require ( "./fold_mode" ) . FoldMode ;
var FoldMode = exports . FoldMode = function ( commentRegex ) {
if ( commentRegex ) {
this . foldingStartMarker = new RegExp (
this . foldingStartMarker . source . replace ( /\|[^|]*?$/ , "|" + commentRegex . start )
) ;
this . foldingStopMarker = new RegExp (
this . foldingStopMarker . source . replace ( /\|[^|]*?$/ , "|" + commentRegex . end )
) ;
}
} ;
oop . inherits ( FoldMode , BaseFoldMode ) ;
( function ( ) {
this . foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/ ;
this . foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/ ;
this . getFoldWidgetRange = function ( session , foldStyle , row , forceMultiline ) {
var line = session . getLine ( row ) ;
var match = line . match ( this . foldingStartMarker ) ;
if ( match ) {
var i = match . index ;
if ( match [ 1 ] )
return this . openingBracketBlock ( session , match [ 1 ] , row , i ) ;
var range = session . getCommentFoldRange ( row , i + match [ 0 ] . length , 1 ) ;
if ( range && ! range . isMultiLine ( ) ) {
if ( forceMultiline ) {
range = this . getSectionRange ( session , row ) ;
} else if ( foldStyle != "all" )
range = null ;
}
return range ;
}
if ( foldStyle === "markbegin" )
return ;
var match = line . match ( this . foldingStopMarker ) ;
if ( match ) {
var i = match . index + match [ 0 ] . length ;
if ( match [ 1 ] )
return this . closingBracketBlock ( session , match [ 1 ] , row , i ) ;
return session . getCommentFoldRange ( row , i , - 1 ) ;
}
} ;
this . getSectionRange = function ( session , row ) {
var line = session . getLine ( row ) ;
var startIndent = line . search ( /\S/ ) ;
var startRow = row ;
var startColumn = line . length ;
row = row + 1 ;
var endRow = row ;
var maxRow = session . getLength ( ) ;
while ( ++ row < maxRow ) {
line = session . getLine ( row ) ;
var indent = line . search ( /\S/ ) ;
if ( indent === - 1 )
continue ;
if ( startIndent > indent )
break ;
var subRange = this . getFoldWidgetRange ( session , "all" , row ) ;
if ( subRange ) {
if ( subRange . start . row <= startRow ) {
break ;
} else if ( subRange . isMultiLine ( ) ) {
row = subRange . end . row ;
} else if ( startIndent == indent ) {
break ;
}
}
endRow = row ;
}
return new Range ( startRow , startColumn , endRow , session . getLine ( endRow ) . length ) ;
} ;
} ) . call ( FoldMode . prototype ) ;
} ) ;