From 9a4a387de65d035a49f1398befc3c8541d1c02c3 Mon Sep 17 00:00:00 2001 From: Adam Jimenez Date: Fri, 6 Jun 2014 10:32:18 +0100 Subject: [PATCH 1/4] Jump To Matching Tag Alt-P: Jump to Matching Tag Alt-Shift-P: Select to Matching Tag fixes #1158 --- lib/ace/commands/default_commands.js | 12 ++++ lib/ace/editor.js | 95 ++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index 77cdfc61..e7cb56ad 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -402,6 +402,18 @@ exports.commands = [{ exec: function(editor) { editor.jumpToMatching(true); }, multiSelectAction: "forEach", readOnly: true +}, { + name: "jumptomatchingtag", + bindKey: bindKey("Alt-P", "Alt-Shift-P"), + exec: function(editor) { editor.jumpToMatchingTag(); }, + multiSelectAction: "forEach", + readOnly: true +}, { + name: "selecttomatchingtag", + bindKey: bindKey("Alt-Shift-P", null), + exec: function(editor) { editor.jumpToMatchingTag(true); }, + multiSelectAction: "forEach", + readOnly: true }, // commands disabled in readOnly mode diff --git a/lib/ace/editor.js b/lib/ace/editor.js index ef2d9f1a..da77e185 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -48,6 +48,7 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter; var CommandManager = require("./commands/command_manager").CommandManager; var defaultCommands = require("./commands/default_commands").commands; var config = require("./config"); +var TokenIterator = require("./token_iterator").TokenIterator; /** * The main entry point into the Ace functionality. @@ -1948,6 +1949,100 @@ var Editor = function(renderer, session) { } }; + /** + * Moves the cursor's row and column to the next matching tag. + * + **/ + this.jumpToMatchingTag = function(select) { + var tag; + var depth = {}; + var sel = {}; + var cursor = this.getCursorPosition(); + var iterator = new TokenIterator(this.session, cursor.row, cursor.column); + var prevToken = iterator.getCurrentToken(); + var token = iterator.stepForward(); + + //get next closing tag + if (!token || token.type.indexOf('tag-name') === -1) { + do { + prevToken = token; + token = iterator.stepForward(); + + if(token && token.type.indexOf('tag-name') !== -1) { + if (isNaN(depth[token.value])) { + depth[token.value] = 0; + } + + if (prevToken.value==='<' ){ + depth[token.value]++; + } else if ( prevToken.value==='=0)); + } + + if (token && token.type.indexOf('tag-name') !== -1) { + sel.end = { + column: iterator.getCurrentTokenColumn()-2, + row: iterator.getCurrentTokenRow() + }; + tag = token.value; + } + + //no tag found + if (!tag) { + return; + } + + //find matching tag + do { + token = prevToken; + prevToken = iterator.stepBackward(); + + if( prevToken ){ + if (prevToken.type.indexOf('tag-close') !== -1) { + sel.start = { + column: iterator.getCurrentTokenColumn()+1, + row: iterator.getCurrentTokenRow() + }; + } + + if (token.value===tag && token.type.indexOf('tag-name') !== -1 && prevToken.value==='<') { + depth[tag]++; + } else if ( token.value===tag && token.type.indexOf('tag-name') !== -1 && prevToken.value===' Date: Mon, 9 Jun 2014 14:12:10 +0100 Subject: [PATCH 2/4] Revert "Jump To Matching Tag" This reverts commit 9a4a387de65d035a49f1398befc3c8541d1c02c3. --- lib/ace/commands/default_commands.js | 12 ---- lib/ace/editor.js | 95 ---------------------------- 2 files changed, 107 deletions(-) diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index e7cb56ad..77cdfc61 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -402,18 +402,6 @@ exports.commands = [{ exec: function(editor) { editor.jumpToMatching(true); }, multiSelectAction: "forEach", readOnly: true -}, { - name: "jumptomatchingtag", - bindKey: bindKey("Alt-P", "Alt-Shift-P"), - exec: function(editor) { editor.jumpToMatchingTag(); }, - multiSelectAction: "forEach", - readOnly: true -}, { - name: "selecttomatchingtag", - bindKey: bindKey("Alt-Shift-P", null), - exec: function(editor) { editor.jumpToMatchingTag(true); }, - multiSelectAction: "forEach", - readOnly: true }, // commands disabled in readOnly mode diff --git a/lib/ace/editor.js b/lib/ace/editor.js index da77e185..ef2d9f1a 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -48,7 +48,6 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter; var CommandManager = require("./commands/command_manager").CommandManager; var defaultCommands = require("./commands/default_commands").commands; var config = require("./config"); -var TokenIterator = require("./token_iterator").TokenIterator; /** * The main entry point into the Ace functionality. @@ -1949,100 +1948,6 @@ var Editor = function(renderer, session) { } }; - /** - * Moves the cursor's row and column to the next matching tag. - * - **/ - this.jumpToMatchingTag = function(select) { - var tag; - var depth = {}; - var sel = {}; - var cursor = this.getCursorPosition(); - var iterator = new TokenIterator(this.session, cursor.row, cursor.column); - var prevToken = iterator.getCurrentToken(); - var token = iterator.stepForward(); - - //get next closing tag - if (!token || token.type.indexOf('tag-name') === -1) { - do { - prevToken = token; - token = iterator.stepForward(); - - if(token && token.type.indexOf('tag-name') !== -1) { - if (isNaN(depth[token.value])) { - depth[token.value] = 0; - } - - if (prevToken.value==='<' ){ - depth[token.value]++; - } else if ( prevToken.value==='=0)); - } - - if (token && token.type.indexOf('tag-name') !== -1) { - sel.end = { - column: iterator.getCurrentTokenColumn()-2, - row: iterator.getCurrentTokenRow() - }; - tag = token.value; - } - - //no tag found - if (!tag) { - return; - } - - //find matching tag - do { - token = prevToken; - prevToken = iterator.stepBackward(); - - if( prevToken ){ - if (prevToken.type.indexOf('tag-close') !== -1) { - sel.start = { - column: iterator.getCurrentTokenColumn()+1, - row: iterator.getCurrentTokenRow() - }; - } - - if (token.value===tag && token.type.indexOf('tag-name') !== -1 && prevToken.value==='<') { - depth[tag]++; - } else if ( token.value===tag && token.type.indexOf('tag-name') !== -1 && prevToken.value===' Date: Mon, 9 Jun 2014 17:09:31 +0100 Subject: [PATCH 3/4] add html tag support to jumpToMatching --- lib/ace/editor.js | 153 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 140 insertions(+), 13 deletions(-) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index ef2d9f1a..f57bdc70 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -48,6 +48,7 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter; var CommandManager = require("./commands/command_manager").CommandManager; var defaultCommands = require("./commands/default_commands").commands; var config = require("./config"); +var TokenIterator = require("./token_iterator").TokenIterator; /** * The main entry point into the Ace functionality. @@ -1915,26 +1916,152 @@ var Editor = function(renderer, session) { }; /** - * Moves the cursor's row and column to the next matching bracket. + * Moves the cursor's row and column to the next matching bracket or HTML tag. * **/ this.jumpToMatching = function(select) { var cursor = this.getCursorPosition(); + var iterator = new TokenIterator(this.session, cursor.row, cursor.column); + var prevToken = iterator.getCurrentToken(); + var token; - var range = this.session.getBracketRange(cursor); - if (!range) { - range = this.find({ - needle: /[{}()\[\]]/g, - preventScroll:true, - start: {row: cursor.row, column: cursor.column - 1} - }); - if (!range) - return; - var pos = range.start; - if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2) - range = this.session.getBracketRange(pos); + //handle bracket as first char on line + if (prevToken && prevToken.index===0) + token = prevToken; + else + token = iterator.stepForward(); + + if (!token) + return; + + //get next closing tag or bracket + var matchType; + var found = false; + var inverse; + var depth = {}; + + do { + if (token.value.match(/[{}()\[\]]/g)) { + for (var i=0; i Date: Mon, 9 Jun 2014 21:30:19 +0100 Subject: [PATCH 4/4] fix jumping to brackets in strings --- lib/ace/editor.js | 87 +++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index f57bdc70..a60e542f 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -1923,48 +1923,54 @@ var Editor = function(renderer, session) { var cursor = this.getCursorPosition(); var iterator = new TokenIterator(this.session, cursor.row, cursor.column); var prevToken = iterator.getCurrentToken(); - var token; + var token = prevToken; - //handle bracket as first char on line - if (prevToken && prevToken.index===0) - token = prevToken; - else + if (!token) token = iterator.stepForward(); if (!token) return; - + //get next closing tag or bracket var matchType; var found = false; - var inverse; var depth = {}; + var i = cursor.column - token.start; + var bracketType; + var brackets = { + ")": "(", + "(": "(", + "]": "[", + "[": "[", + "{": "{", + "}": "{" + }; do { if (token.value.match(/[{}()\[\]]/g)) { - for (var i=0; i