Tag replacement syncing improved & available again

This commit is contained in:
Matt Pass
2016-08-12 18:56:57 +01:00
parent f8bbe45de7
commit f1a4710aea
2 changed files with 152 additions and 122 deletions

View File

@@ -389,34 +389,36 @@ var ICEcoder = {
// On before change
cMonBeforeChange: function(thisCM,cMinstance,changeObj,cM) {
var sels, tokenString, range, canMaybeReplace, thisData;
var sels, tokenInfo, lineContent, range, thisData;
// For each of the user selections
sels = thisCM.listSelections();
for (var i=0; i<sels.length; i++) {
// Get the token at the cursor start (anchor) position
tokenString = thisCM.getTokenAt(sels[i].anchor);
// Get the token info at the cursor start (anchor) position
tokenInfo = thisCM.getTokenAt(sels[i].anchor);
// If we're just inside a tag, move along 1 char pos and get token info at that position
if (tokenString.type == "tag bracket" && tokenString.string == "<") {
tokenString = thisCM.getTokenAt({line: sels[i].anchor.line, ch: sels[i].anchor.ch+1});
if (tokenInfo.type == "tag bracket" && tokenInfo.string == "<") {
tokenInfo = thisCM.getTokenAt({line: sels[i].anchor.line, ch: sels[i].anchor.ch+1});
}
// If we're inside a tag now
if (tokenString.type == "tag") {
if (tokenInfo.type == "tag") {
// Get line content and if more than 1 tag instance of string we're editing, skip
lineContent = thisCM.getLine(sels[i].anchor.line);
if ((lineContent.match(new RegExp("<"+tokenInfo.string, "g")) || []).length > 1) {
continue;
}
// Test for range info
range = cM.fold['xml'](thisCM, sels[i].anchor);
canMaybeReplace = true;
for (var j=0; j<top.ICEcoder.endTagReplaceData.length; j++) {
// If we have range info and we're start and end are on the same line
if ("undefined" != typeof range && top.ICEcoder.endTagReplaceData[j].split(";")[1] == range.to.line + ":" + range.to.ch) {
canMaybeReplace = false;
}
}
// If we can still replace and have range info and not undoing/redoing (as that replaces chunks itself)
if (canMaybeReplace && "undefined" != typeof range && changeObj.origin != "undo" && changeObj.origin != "redo") {
// If we have range info and not undoing/redoing (as that replaces chunks itself)
if ("undefined" != typeof range && changeObj.origin != "undo" && changeObj.origin != "redo") {
// Work out the data string to set and if not in array, push in ready to handle on change event
thisData = tokenString.string + ";" + range.to.line + ":" + range.to.ch;
thisData = tokenInfo.string + ";" + range.to.line + ":" + range.to.ch;
if (top.ICEcoder.endTagReplaceData.indexOf(thisData) == -1) {
top.ICEcoder.endTagReplaceData.push(thisData);
// Also set the position of the end tag on this line if found
top.ICEcoder.thisLinesEndTagPos = lineContent.indexOf('/'+tokenInfo.string+'>');
}
}
}
@@ -425,7 +427,7 @@ var ICEcoder = {
// On change
cMonChange: function(thisCM,cMinstance,changeObj) {
var rData, thisToken, repl1, repl2, tTS, filepath, filename, fileExt;
var rData, thisLine, thisChar, repl1, repl2, thisToken, tTS, filepath, filename, fileExt;
// If we're not loading the file, it's a change, so update tab
if (!top.ICEcoder.loadingFile) {
@@ -440,27 +442,54 @@ var ICEcoder = {
// If we're replacing end tag strings, do that
if (top.ICEcoder.endTagReplaceData.length > 0) {
// For each one of them, grab our data to work with
for (var i=0; i<top.ICEcoder.endTagReplaceData.length; i++) {
// Extract data from that string
rData = top.ICEcoder.endTagReplaceData[i].split(";");
thisLine = rData[1].split(":")[0]*1;
thisChar = rData[1].split(":")[1]*1;
// Don't do anything if it's the same line, as we can't rely on fold range data due to nested tags
if (rData[1].split(":")[0]*1 == changeObj.from.line) {
continue;
// If the start & end tags are within the same line
if (thisLine == changeObj.from.line) {
// Just the 1 tag of that type on this line?
if (top.ICEcoder.thisLinesEndTagPos > -1) {
repl1 = {line: thisLine, ch: top.ICEcoder.thisLinesEndTagPos+2};
repl2 = {line: thisLine, ch: top.ICEcoder.thisLinesEndTagPos+2+rData[0].length};
} else {
continue;
}
// Not within the same line
} else {
// Otherwise, work out the replace ranges
repl1 = {line: thisLine, ch: thisChar+2};
repl2 = {line: thisLine, ch: thisChar+2+rData[0].length};
}
// Otherwise, work out the replace ranges
repl1 = {line: rData[1].split(":")[0]*1, ch: (rData[1].split(":")[1]*1)+2};
repl2 = {line: rData[1].split(":")[0]*1, ch: (rData[1].split(":")[1]*1)+2+rData[0].length};
// Set a blank this token string
tTS = "";
// Establish the string to replace with
thisToken = thisCM.getTokenAt(thisCM.listSelections()[i].anchor);
tTS = thisToken.string;
// Traverse backwards through string to get to non whitespace chars
// This allows us to get the tag name and ignore attributes
for (var j=0; j<10000; j++) {
if (thisCM.listSelections()[i]) {
thisToken = thisCM.getTokenAt({line: thisCM.listSelections()[i].anchor.line, ch: thisCM.listSelections()[i].anchor.ch-j});
tTS = thisToken.string;
if (tTS.trim() != "") {
break;
}
}
}
// If we ended up at the left arrow of the tag, set this token string to blank
if (tTS == "<" ) {
tTS = "";
}
// Replace our string over the range
// Disabled for now, as buggy
// thisCM.replaceRange(tTS, repl1, repl2);
// Replace our string over the range, if this token string isn't blank and the end tag matches our original tag
if (tTS.trim() != "" && thisCM.getRange(repl1,repl2) == rData[0]) {
thisCM.replaceRange(tTS, repl1, repl2);
}
}
}