diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js index 259180f3..b8d84157 100644 --- a/lib/ace/mode/behaviour/cstyle.js +++ b/lib/ace/mode/behaviour/cstyle.js @@ -35,6 +35,10 @@ var oop = require("../../lib/oop"); var Behaviour = require("../behaviour").Behaviour; var TokenIterator = require("../../token_iterator").TokenIterator; +var autoInsertedBrackets = 0; +var autoInsertedRow = -1; +var autoInsertedLineEnd = ""; + var CstyleBehaviour = function () { CstyleBehaviour.isSaneInsertion = function(editor, session) { @@ -58,6 +62,29 @@ var CstyleBehaviour = function () { 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); + // Reset previous state if text or context changed too much + if (!this.isAutoInsertedClosing(cursor, line, autoInsertedLineEnd[0])) + autoInsertedBrackets = 0; + autoInsertedRow = cursor.row; + autoInsertedLineEnd = bracket + line.substr(cursor.column); + autoInsertedBrackets++; + }; + + CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) { + return autoInsertedBrackets > 0 && + cursor.row === autoInsertedRow && + bracket === autoInsertedLineEnd[0] && + line.substr(cursor.column) === autoInsertedLineEnd; + }; + + CstyleBehaviour.popAutoInsertedClosing = function() { + autoInsertedLineEnd = autoInsertedLineEnd.substr(1); + autoInsertedBrackets--; + }; this.add("braces", "insertion", function (state, action, editor, session, text) { if (text == '{') { @@ -71,6 +98,7 @@ var CstyleBehaviour = function () { selection: false }; } else { + CstyleBehaviour.recordAutoInsert(editor, session, "}"); return { text: '{}', selection: [1, 1] @@ -82,7 +110,8 @@ var CstyleBehaviour = function () { 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) { + if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { + CstyleBehaviour.popAutoInsertedClosing(); return { text: '', selection: [1, 1] @@ -133,6 +162,7 @@ var CstyleBehaviour = function () { selection: false }; } else { + CstyleBehaviour.recordAutoInsert(editor, session, ")"); return { text: '()', selection: [1, 1] @@ -144,7 +174,8 @@ var CstyleBehaviour = function () { 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) { + if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { + CstyleBehaviour.popAutoInsertedClosing(); return { text: '', selection: [1, 1] @@ -178,6 +209,7 @@ var CstyleBehaviour = function () { selection: false }; } else { + CstyleBehaviour.recordAutoInsert(editor, session, "]"); return { text: '[]', selection: [1, 1] @@ -189,7 +221,8 @@ var CstyleBehaviour = function () { 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) { + if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { + CstyleBehaviour.popAutoInsertedClosing(); return { text: '', selection: [1, 1]