From 943e690bf60bd9d973532cf6ab7d4966f280dd11 Mon Sep 17 00:00:00 2001 From: nightwing Date: Tue, 12 Mar 2013 13:49:14 +0400 Subject: [PATCH] bugfix --- lib/ace/anchor.js | 130 +++++++++++++-------------- lib/ace/editor.js | 3 +- lib/ace/snippets.js | 106 ++++++++++++++-------- lib/ace/snippets/javascript.snippets | 28 +++--- lib/ace/tokenizer.js | 2 +- 5 files changed, 148 insertions(+), 121 deletions(-) diff --git a/lib/ace/anchor.js b/lib/ace/anchor.js index e87f4900..d2ffd090 100644 --- a/lib/ace/anchor.js +++ b/lib/ace/anchor.js @@ -3,7 +3,7 @@ * * Copyright (c) 2010, Ajax.org B.V. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright @@ -14,7 +14,7 @@ * * Neither the name of Ajax.org B.V. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -35,7 +35,7 @@ var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; /** - * + * * Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated. * * @class Anchor @@ -53,7 +53,7 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter; var Anchor = exports.Anchor = function(doc, row, column) { this.document = doc; - + if (typeof column == "undefined") this.setPosition(row.row, row.column); else @@ -66,7 +66,7 @@ var Anchor = exports.Anchor = function(doc, row, column) { (function() { oop.implement(this, EventEmitter); - + /** * Returns an object identifying the `row` and `column` position of the current anchor. * @returns {Object} @@ -75,28 +75,28 @@ var Anchor = exports.Anchor = function(doc, row, column) { this.getPosition = function() { return this.$clipPositionToDocument(this.row, this.column); }; - - /** - * + + /** + * * Returns the current document. * @returns {Document} **/ - + this.getDocument = function() { return this.document; }; - - /** + + /** * Fires whenever the anchor position changes. * * Both of these objects have a `row` and `column` property corresponding to the position. * * Events that can trigger this function include [[Anchor.setPosition `setPosition()`]]. - * - * @event change - * @param {Object} e An object containing information about the anchor position. It has two properties: + * + * @event change + * @param {Object} e An object containing information about the anchor position. It has two properties: * - `old`: An object describing the old Anchor position - * - `value`: An object describing the new Anchor position + * - `value`: An object describing the new Anchor position * * **/ @@ -104,60 +104,57 @@ var Anchor = exports.Anchor = function(doc, row, column) { this.onChange = function(e) { var delta = e.data; var range = delta.range; - + if (range.start.row == range.end.row && range.start.row != this.row) return; - + if (range.start.row > this.row) return; - + if (range.start.row == this.row && range.start.column > this.column) return; - + var row = this.row; var column = this.column; - + var start = range.start; + var end = range.end; + if (delta.action === "insertText") { - if (range.start.row === row && range.start.column <= column) { - if (range.start.row === range.end.row) { - column += range.end.column - range.start.column; + if (start.row === row && start.column <= column) { + if (start.row === end.row) { + column += end.column - start.column; + } else { + column -= start.column; + row += end.row - start.row; } - else { - column -= range.start.column; - row += range.end.row - range.start.row; - } - } - else if (range.start.row !== range.end.row && range.start.row < row) { - row += range.end.row - range.start.row; + } else if (start.row !== end.row && start.row < row) { + row += end.row - start.row; } } else if (delta.action === "insertLines") { - if (range.start.row <= row) { - row += range.end.row - range.start.row; + if (start.row <= row) { + row += end.row - start.row; } - } - else if (delta.action == "removeText") { - if (range.start.row == row && range.start.column < column) { - if (range.end.column >= column) - column = range.start.column; + } else if (delta.action === "removeText") { + if (start.row === row && start.column < column) { + if (end.column >= column) + column = start.column; else - column = Math.max(0, column - (range.end.column - range.start.column)); - - } else if (range.start.row !== range.end.row && range.start.row < row) { - if (range.end.row == row) { - column = Math.max(0, column - range.end.column) + range.start.column; - } - row -= (range.end.row - range.start.row); - } - else if (range.end.row == row) { - row -= range.end.row - range.start.row; - column = Math.max(0, column - range.end.column) + range.start.column; + column = Math.max(0, column - (end.column - start.column)); + + } else if (start.row !== end.row && start.row < row) { + if (end.row === row) + column = Math.max(0, column - end.column) + start.column; + row -= (end.row - start.row); + } else if (end.row === row) { + row -= end.row - start.row; + column = Math.max(0, column - end.column) + start.column; } } else if (delta.action == "removeLines") { - if (range.start.row <= row) { - if (range.end.row <= row) - row -= range.end.row - range.start.row; + if (start.row <= row) { + if (end.row <= row) + row -= end.row - start.row; else { - row = range.start.row; + row = start.row; column = 0; } } @@ -166,13 +163,13 @@ var Anchor = exports.Anchor = function(doc, row, column) { this.setPosition(row, column, true); }; - /** + /** * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped. * @param {Number} row The row index to move the anchor to * @param {Number} column The column index to move the anchor to * @param {Boolean} noClip Identifies if you want the position to be clipped * - * + * * **/ @@ -183,19 +180,18 @@ var Anchor = exports.Anchor = function(doc, row, column) { row: row, column: column }; - } - else { + } else { pos = this.$clipPositionToDocument(row, column); } - + if (this.row == pos.row && this.column == pos.column) return; - + var old = { row: this.row, column: this.column }; - + this.row = pos.row; this.column = pos.column; this._emit("change", { @@ -203,7 +199,7 @@ var Anchor = exports.Anchor = function(doc, row, column) { value: pos }); }; - + /** * When called, the `'change'` event listener is removed. * @@ -212,18 +208,16 @@ var Anchor = exports.Anchor = function(doc, row, column) { this.detach = function() { this.document.removeEventListener("change", this.$onChange); }; - - /** + + /** * Clips the anchor position to the specified row and column. * @param {Number} row The row index to clip the anchor to * @param {Number} column The column index to clip the anchor to * - * - * **/ this.$clipPositionToDocument = function(row, column) { var pos = {}; - + if (row >= this.document.getLength()) { pos.row = Math.max(0, this.document.getLength() - 1); pos.column = this.document.getLine(pos.row).length; @@ -236,13 +230,13 @@ var Anchor = exports.Anchor = function(doc, row, column) { pos.row = row; pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column)); } - + if (column < 0) pos.column = 0; - + return pos; }; - + }).call(Anchor.prototype); }); diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 87d06d89..1566bc25 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -2241,7 +2241,8 @@ config.defineOptions(Editor.prototype, "editor", { useWorker: "session", useSoftTabs: "session", tabSize: "session", - wrap: "session" + wrap: "session", + foldStyle: "session" }); exports.Editor = Editor; diff --git a/lib/ace/snippets.js b/lib/ace/snippets.js index 43909e58..dee004ff 100644 --- a/lib/ace/snippets.js +++ b/lib/ace/snippets.js @@ -36,7 +36,8 @@ var HashHandler = require("./keyboard/hash_handler").HashHandler; var Tokenizer = require("./tokenizer").Tokenizer; var SnippetManager = function() { - this.snippets = []; + this.snippetMap = {}; + this.snippetNameMap = {}; }; (function() { @@ -52,10 +53,17 @@ var SnippetManager = function() { } SnippetManager.$tokenizer = new Tokenizer({ start: [ - {regex: /\\[$}`\\]/, token: function(val, state, stack) { - if (val[1] == "}" && !stack.length) - return [val]; - return [val[1]]; + {regex: /\\./, token: function(val, state, stack) { + if (stack.escapes == null) + stack.escapes = "`$\\"; + var ch = val[1]; + if ( + stack.escapes.indexOf(ch) == -1 || + (ch == "}" && stack.length) + ) { + val = ch; + } + return [val]; }}, {regex: /}/, token: function(val, state, stack) { return [stack.length ? stack.shift() : val]; @@ -85,14 +93,12 @@ var SnippetManager = function() { stack[0].code = val.splice(1, -1); return ""; }, next: "start"}, + {regex: ":[+-?]", token: "", next: "start"}, {regex: ":|", token: "", next: "start"} ], formatString: [ - {regex: /\\[ulULEnt/]/, token: "escape"}, - {include: "$"} - ], - formatStringVar: [ - + {regex: /\\[ulULEnt/]/, token: "escape"}, + {include: "$"} ] }); SnippetManager.prototype.getTokenizer = function() { @@ -144,7 +150,7 @@ var SnippetManager = function() { // returns string formatted according to http://manual.macromates.com/en/regular_expressions#replacement_string_syntax_format_strings this.tmStrFormat = function(str, regex, fmt, flags) { - var re = new RegExp(regex, flags.replace(/[^gi]/, "")); + var re = new RegExp(regex, flags.replace(/[^gi]/, "")); var fmtTokens = this.getTokenizer().getLineTokens(fmt, "formatString"); return str.replace(re, function() { @@ -320,35 +326,54 @@ var SnippetManager = function() { }; this.snippetMap = {}; + this.snippetNameMap = {}; this.register = function(snippets, scope) { var snippetMap = this.snippetMap; + var snippetNameMap = this.snippetNameMap; + function wrapRegexp(src) { + if (src && !/^\^?\(.*\)\$?$|^\\b$/.test(src)) + src = "(?:" + src + ")" + + return src || ""; + } + function guardedRegexp(re, guard, opening) { + re = wrapRegexp(re); + guard = wrapRegexp(guard); + if (opening) { + re = guard + re; + if (re && re[re.length - 1] != "$") + re = re + "$"; + } else { + re = re + guard; + if (re && re[0] != "^") + re = "^" + re; + } + return new RegExp(re); + } + function addSnippet(s) { if (!s.scope) s.scope = scope || "_"; - if (!snippetMap[s.scope]) - snippetMap[s.scope] = []; - snippetMap[s.scope].push(s); + scope = s.scope + if (!snippetMap[scope]) { + snippetMap[scope] = []; + snippetNameMap[scope] = {}; + } + snippetMap[scope].push(s); + if (s.name) + snippetNameMap[scope][s.name] = s; - if (s.tabTrigger) { - if (/^\w/.test(s.tabTrigger)) - s.guard = "\\b"; + if (s.tabTrigger && !s.trigger) { + if (!s.guard && /^\w/.test(s.tabTrigger)) + s.guard = "\\\\b"; s.trigger = lang.escapeRegExp(s.tabTrigger); } - s.startRe = (s.guard || "") + (s.trigger || ""); - if (s.startRe && s.startRe[s.startRe - 1] != "$") - s.startRe += "$"; - if (s.startRe) - s.startRe = new RegExp(s.startRe); - s.endRe = (s.endGuard || "") + (s.endTrigger || ""); - if (s.endRe && s.endRe[0] != "^") - s.endRe = "^" + s.endRe; - if (s.endRe) - s.endRe = new RegExp(s.endRe); - if (s.trigger) - s.triggerRe = new RegExp(s.trigger + "$"); - if (s.endTrigger) - s.endTriggerRe = new RegExp("^" + s.endTrigger); + s.startRe = guardedRegexp(s.trigger, s.guard, true); + s.triggerRe = new RegExp(s.trigger, "", true); + + s.endRe = guardedRegexp(s.endTrigger, s.endGuard, true); + s.endTriggerRe = new RegExp(s.endTrigger, "", true); }; if (snippets.content) @@ -379,10 +404,9 @@ var SnippetManager = function() { snippet.endTrigger = val[3]; snippet.endGuard = val[4]; } else if (key == "snippet") { - val = val.split(/^(\S*)(?:\s(.*))?$/); - snippet.tabTrigger = val[1]; + snippet.tabTrigger = val.split(/^(\S*)(?:\s(.*))?$/)[1]; if (!snippet.name) - snippet.name = val[2]; + snippet.name = val; } else { snippet[key] = val; } @@ -432,7 +456,8 @@ var TabstopManager = function(editor) { this.onChange = function(e) { var changeRange = e.data.range; - if (e.data.action[0] == "i"){ + var isInsert = e.data.action[0] == "i"; + if (isInsert) { var start = changeRange.start; var end = changeRange.end; } else { @@ -446,14 +471,16 @@ var TabstopManager = function(editor) { var colDiff = end.column - start.column; var ranges = this.ranges; +console.log(e.data) for (var i = 0; i < ranges.length; i++) { var r = ranges[i]; - if (r.end.row < startRow) + if (r.end.row < changeRange.start.row) continue; - +var b=r.clone() if (Range.comparePoints(changeRange.start, r.start) < 0 && Range.comparePoints(changeRange.end, r.end) > 0) { this.removeRange(r); + console.log(1) i--; continue; } @@ -470,6 +497,9 @@ var TabstopManager = function(editor) { if (r.end.row >= startRow) { r.end.row += lineDif; } + console.log(b+r+"") + if (Range.comparePoints(r.start, r.end) > 0) + this.removeRange(r); } }; this.onChangeSelection = function() { @@ -506,7 +536,7 @@ var TabstopManager = function(editor) { this.addTabstopMarkers(ts); this.index = index; ts = this.tabstops[this.index]; - if (!ts) + if (!ts || !ts.length) return; this.selectedTabstop = ts; diff --git a/lib/ace/snippets/javascript.snippets b/lib/ace/snippets/javascript.snippets index fe1d5bcf..b5c4f72c 100644 --- a/lib/ace/snippets/javascript.snippets +++ b/lib/ace/snippets/javascript.snippets @@ -1,6 +1,6 @@ # Prototype snippet proto - ${1:class_name}.prototype.${2:method_name} = function(${3:first_argument}) { + ${1:class_name}.prototype.${2:method_name} = function(${3irst_argument}) { ${4:// body...} }; # Function @@ -9,17 +9,17 @@ snippet fun ${3:// body...} } # Anonymous Function -regex /\b(\()?/f//(\))?/ +regex /(=)\s*|(:)\s*|(\()|\b/f/(\))?/ name f - function($1) { + function${M1||M2||M3? ${1:functionName $: }}($2) { ${0:$TM_SELECTED_TEXT} - }; + }${M1?;}${M2?,}${M3?)} # Immediate function trigger \(?f\( endTrigger \)? snippet f( (function(${1}) { - ${3:/* code */} + ${0:${TM_SELECTED_TEXT:/* code */}} }(${1})); # if snippet if @@ -72,8 +72,9 @@ snippet do } while (${1:/* condition */}); # Object Method snippet :f +regex /([,{[])|^\s*/:f/ ${1:method_name}: function(${2:attribute}) { - ${4} + ${0} }${3:,} # setTimeout function snippet timeout @@ -105,6 +106,7 @@ snippet /** * */ snippet @par +regex /^\s*\*\s*/@(para?m?)?/ @param {${1:type}} ${2:name} ${3:description} snippet @ret @return {${1:type}} ${2:description} @@ -176,14 +178,14 @@ snippet for- snippet for ?in -regex /^\s*/for (\w+\b)?( \d+)( \d+)?/ - +regex /^\s*/for\b\s*(\w+\b)?(\s*\d+\b)(\s*\d*)/ + 78789 regex /^\s*/for (\w+) in (\w+)/ - ${include:for $1=$M1,$2=$M2} -regex /^\s*/for (\w*) (\w+)(.l?e?n?[ght]{0,3})/ - ${include:for $1=$M1,$2=$M2} + ${include:for $1=$M1,$2=$M2}44 +regex /^\s*/for\b( \w+\b)?( \w+\b)(\.l?e?n?[ght]{0,3})/ + ${include:for $1=$M1,$2=$M2}44 regex /^\s*/for (\w+) in (\w+)/ - ${include:for $1=$M1,$2=$M2} + ${include:for $1=$M1,$2=$M2}44 #modules @@ -200,5 +202,5 @@ guard ^\s* $0 snippet Req guard ^\s* - var ${1/.*\/(.)/\u$1/} = require("${1}").${1_0}; + var ${1/.*\/(.)/\u$1/} = require("${1}").${1!0}; $0 diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js index cf79a02b..f6c93d1d 100644 --- a/lib/ace/tokenizer.js +++ b/lib/ace/tokenizer.js @@ -277,7 +277,7 @@ var Tokenizer = function(rules) { tokens.push(token); token = {type: type, value: value}; } - } else { + } else if (type) { if (token.type) tokens.push(token); token = {type: null, value: ""};