From 2950c67e3e8c86ea2df56cddfae910e6ccf61f93 Mon Sep 17 00:00:00 2001 From: Lennart Kats Date: Thu, 18 Oct 2012 10:23:55 +0200 Subject: [PATCH 1/6] Don't surround bracketize brackets when you're trying to overwrite them --- lib/ace/mode/behaviour/cstyle.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js index e4dea304..5f2e48b4 100644 --- a/lib/ace/mode/behaviour/cstyle.js +++ b/lib/ace/mode/behaviour/cstyle.js @@ -40,7 +40,7 @@ var CstyleBehaviour = function () { if (text == '{') { var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); - if (selected !== "") { + if (selected !== "" && selected !== "}") { return { text: '{' + selected + '}', selection: false @@ -100,7 +100,7 @@ var CstyleBehaviour = function () { if (text == '(') { var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); - if (selected !== "") { + if (selected !== "" && selected !== ")") { return { text: '(' + selected + ')', selection: false @@ -143,7 +143,7 @@ var CstyleBehaviour = function () { if (text == '[') { var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); - if (selected !== "") { + if (selected !== "" && selected !== "]") { return { text: '[' + selected + ']', selection: false @@ -187,7 +187,7 @@ var CstyleBehaviour = function () { var quote = text; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); - if (selected !== "") { + if (selected !== "" && selected !== "'") { return { text: quote + selected + quote, selection: false From 5ed0998ce77ccc25ad7d1141df23864f854f4e6b Mon Sep 17 00:00:00 2001 From: Lennart Kats Date: Thu, 18 Oct 2012 14:41:35 +0200 Subject: [PATCH 2/6] Be selective when auto-inserting brackets --- lib/ace/mode/behaviour/cstyle.js | 38 ++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js index 5f2e48b4..0efac142 100644 --- a/lib/ace/mode/behaviour/cstyle.js +++ b/lib/ace/mode/behaviour/cstyle.js @@ -33,14 +33,40 @@ define(function(require, exports, module) { var oop = require("../../lib/oop"); var Behaviour = require("../behaviour").Behaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; var CstyleBehaviour = function () { + + CstyleBehaviour.isSaneInsertion = function(editor, session) { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + + // Don't insert in the middle of a keyword/identifier/lexical + if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text"])) { + // Look ahead in case we're at the end of a token + iterator = new TokenIterator(session, cursor.row, cursor.column + 1); + if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text"])) + return false; + } + + // Don't insert in front of identifiers or brackets + iterator.stepForward(); + if (this.$matchTokenType(iterator.getCurrentToken() || "text", ["identifier", "paren.lparen"])) + return false; + return true; + }; + + CstyleBehaviour.$matchTokenType = function(token, types) { + return types.indexOf(token.type || token) > -1; + }; this.add("braces", "insertion", function (state, action, editor, session, text) { if (text == '{') { + if (!CstyleBehaviour.isSaneInsertion(editor, session)) + return; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); - if (selected !== "" && selected !== "}") { + if (selected !== "" && selected !== "{") { return { text: '{' + selected + '}', selection: false @@ -98,9 +124,11 @@ var CstyleBehaviour = function () { this.add("parens", "insertion", function (state, action, editor, session, text) { if (text == '(') { + if (!CstyleBehaviour.isSaneInsertion(editor, session)) + return; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); - if (selected !== "" && selected !== ")") { + if (selected !== "") { return { text: '(' + selected + ')', selection: false @@ -141,9 +169,11 @@ var CstyleBehaviour = function () { this.add("brackets", "insertion", function (state, action, editor, session, text) { if (text == '[') { + if (!CstyleBehaviour.isSaneInsertion(editor, session)) + return; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); - if (selected !== "" && selected !== "]") { + if (selected !== "") { return { text: '[' + selected + ']', selection: false @@ -187,7 +217,7 @@ var CstyleBehaviour = function () { var quote = text; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); - if (selected !== "" && selected !== "'") { + if (selected !== "") { return { text: quote + selected + quote, selection: false From b126f5d314945d57c402e34cf40c39262126ed1a Mon Sep 17 00:00:00 2001 From: Lennart Kats Date: Thu, 18 Oct 2012 15:32:31 +0200 Subject: [PATCH 3/6] Allow multiple bracket closing insertionss like {{{}}} --- lib/ace/mode/behaviour/cstyle.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js index 0efac142..259180f3 100644 --- a/lib/ace/mode/behaviour/cstyle.js +++ b/lib/ace/mode/behaviour/cstyle.js @@ -45,15 +45,14 @@ var CstyleBehaviour = function () { if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text"])) { // Look ahead in case we're at the end of a token iterator = new TokenIterator(session, cursor.row, cursor.column + 1); - if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text"])) + if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "paren.rparen"])) return false; } - // Don't insert in front of identifiers or brackets + // Only insert in front of whitespace/comments iterator.stepForward(); - if (this.$matchTokenType(iterator.getCurrentToken() || "text", ["identifier", "paren.lparen"])) - return false; - return true; + return iterator.getCurrentTokenRow() !== cursor.row || + this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "comment", "paren.rparen"]); }; CstyleBehaviour.$matchTokenType = function(token, types) { From 99f695310821d81d176be48dcb80c3b89a3750b5 Mon Sep 17 00:00:00 2001 From: Lennart Kats Date: Thu, 18 Oct 2012 15:55:33 +0200 Subject: [PATCH 4/6] Only skip closing brackets if they were just auto-inserted --- lib/ace/mode/behaviour/cstyle.js | 39 +++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) 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] From 40bc5ee79af4097ea13fc19d5022c16d46834c13 Mon Sep 17 00:00:00 2001 From: Lennart Kats Date: Thu, 18 Oct 2012 17:29:15 +0200 Subject: [PATCH 5/6] Allow bracket insertion after closing bracket: }() --- lib/ace/mode/behaviour/cstyle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js index b8d84157..76e12fc3 100644 --- a/lib/ace/mode/behaviour/cstyle.js +++ b/lib/ace/mode/behaviour/cstyle.js @@ -46,7 +46,7 @@ var CstyleBehaviour = function () { var iterator = new TokenIterator(session, cursor.row, cursor.column); // Don't insert in the middle of a keyword/identifier/lexical - if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text"])) { + if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "paren.rparen"])) { // Look ahead in case we're at the end of a token iterator = new TokenIterator(session, cursor.row, cursor.column + 1); if (!this.$matchTokenType(iterator.getCurrentToken() || "text", ["text", "paren.rparen"])) From 72dde40c76c50f08b1bb21a3cd5acfc3ac188166 Mon Sep 17 00:00:00 2001 From: Lennart Kats Date: Mon, 22 Oct 2012 14:17:08 +0200 Subject: [PATCH 6/6] Make sure wrapping behaves the same as before --- lib/ace/mode/behaviour/cstyle.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js index 76e12fc3..8397e79c 100644 --- a/lib/ace/mode/behaviour/cstyle.js +++ b/lib/ace/mode/behaviour/cstyle.js @@ -88,8 +88,6 @@ var CstyleBehaviour = function () { this.add("braces", "insertion", function (state, action, editor, session, text) { if (text == '{') { - if (!CstyleBehaviour.isSaneInsertion(editor, session)) - return; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && selected !== "{") { @@ -97,7 +95,7 @@ var CstyleBehaviour = function () { text: '{' + selected + '}', selection: false }; - } else { + } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { CstyleBehaviour.recordAutoInsert(editor, session, "}"); return { text: '{}', @@ -152,8 +150,6 @@ var CstyleBehaviour = function () { this.add("parens", "insertion", function (state, action, editor, session, text) { if (text == '(') { - if (!CstyleBehaviour.isSaneInsertion(editor, session)) - return; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "") { @@ -161,7 +157,7 @@ var CstyleBehaviour = function () { text: '(' + selected + ')', selection: false }; - } else { + } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { CstyleBehaviour.recordAutoInsert(editor, session, ")"); return { text: '()', @@ -199,8 +195,6 @@ var CstyleBehaviour = function () { this.add("brackets", "insertion", function (state, action, editor, session, text) { if (text == '[') { - if (!CstyleBehaviour.isSaneInsertion(editor, session)) - return; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "") { @@ -208,7 +202,7 @@ var CstyleBehaviour = function () { text: '[' + selected + ']', selection: false }; - } else { + } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { CstyleBehaviour.recordAutoInsert(editor, session, "]"); return { text: '[]',