Here is a way to do it without evil regex strings. Instead I wanted to try and do it with jQuery 'keydown' event which was inline with what the questioner mentioned (see: newb at jQuery). Also note that 'keydown' is better for this methodology as 'keyup' will fire multiple times, though I guess this will too... Anyways, here is what I came up with:
$('#inputFieldInQuestion').on('keydown', function (event) {
// if both the control key and left key are pushed
if (event.keyCode == 37 && event.ctrlKey) {
// grab the text from the input and caret position in the input box
var inputBoxText = $(this).val(),
currentCaretPosition = this.selectionStart
// loop through all the characters in the input box text
for (var i = 0; i < inputBoxText.length; i++) {
// if the current character is an open bracket start testing for the end
if (inputBoxText[i] === "[") {
for (var j = i + 1; j < inputBoxText.length; j++) {
// this means that there is another bracketed string in between the
// beginning and the current bracketed string
if (inputBoxText[j] === "[") { break }
// if instead we come to the end of the bracketed string will determine
// if the bounds make sense
else if (inputBoxText[j] === "]") {
// if the caret position is in the bounds that you have just created
// we continue the shift
if (currentCaretPosition > i && currentCaretPosition < j) {
// test as per the question if the bracketed string is adjascent
// to another bracketed string
if (inputBoxText[i - 1] !== "]") {
// if the bracketed text is all the way to the left of the
// input box
if (i > 0) {
// slice and dice the string and move things left by one
// character
var frontString = inputBoxText.substring(0, i),
stringToMove = inputBoxText.substring(i, j + 1),
endString = inputBoxText.substring(j + 1)
$(this).val(frontString.slice(0, i - 1) + stringToMove + frontString.slice(i - 1) + endString)
this.setSelectionRange(currentCaretPosition - 1, currentCaretPosition - 1); break
}
}
else { break }
}
}
}
}
}
// important so that the ctrl-left doesn't shift the cursor to the end of the word
return false;
}
// if both the control key and right key are pushed
else if (event.keyCode == 39 && event.ctrlKey) {
var inputBoxText = $(this).val(),
currentCaretPosition = this.selectionStart
for (var i = 0; i < inputBoxText.length; i++) {
if (inputBoxText[i] === "[") {
for (var j = i; j < inputBoxText.length; j++) {
if (inputBoxText[j] === "]") {
if (currentCaretPosition > i && currentCaretPosition < j) {
// test as per the question if the bracketed string is adjascent
// to another bracketed string
if (inputBoxText[j + 1] !== "[") {
// bracketed text is all the way to the right of the input box
if (inputBoxText.length - j > 1) {
var frontString = inputBoxText.substring(0, i),
stringToMove = inputBoxText.substring(i, j + 1),
endString = inputBoxText.substring(j + 1)
$(this).val(frontString + endString.slice(0, 1) + stringToMove + endString.slice(1))
this.setSelectionRange(currentCaretPosition + 1, currentCaretPosition + 1); break
}
}
else { break }
}
}
}
}
}
return false;
}
})
This might be the most complicated way to do this ever but it does seem to work and satisfy all the constraints posed. Since I just noticed that this was flagged regex, this might be a terrible solution. Let the evisceration begin!
Super Bonus: This will work if you have any number of "[]" pairs in the string.