--- /dev/null
+// plugin Move Caret To Word End
+// version 0.0
+// release March 2016
+// author Plugin Fan
+// license GPL v 3.0
+
+// Moves all carets to the closest word end :
+// - Ctrl-NumPad6 - Move Caret to Next Word End
+// - Ctrl-NumPad4 - Move Caret to Previous Word End
+//
+// When moving word-by-word, the IDE's builtin algorithm stops on word starts. Often you can reach the word end only by
+// moving one word further then moving a couple of characters back. But this may not be an option when using multiple
+// carets and there are different amounts of separators between the words.
+
+import com.intellij.openapi.actionSystem.AnActionEvent
+import static liveplugin.PluginUtil.*
+
+// perform the caret movement
+def moveCaretToWordEnd(event, direction)
+{
+ // direction specific movement parameters
+ def search = [
+ 'forward': ['step': +1, 'check': 0, 'match': true ],
+ 'backward': ['step': -1, 'check': -1, 'match': false],
+ ][direction]
+
+ runDocumentWriteAction(event.project) {
+ currentEditorIn(event.project).with {
+ caretModel.getAllCarets().each { caret ->
+ def offset = caret.offset
+ def text = document.getCharsSequence()
+ def size = text.size()
+
+ // move to closest position from where the closest word end becomes visible
+ while (offset + search.check >= 0 && offset + search.check < size && Character.isLetterOrDigit(text.charAt(offset + search.check)) != search.match)
+ offset += search.step
+
+ // move to closest word end
+ while (offset + search.check >= 0 && offset + search.check < size && Character.isLetterOrDigit(text.charAt(offset + search.check)) == search.match)
+ offset += search.step
+
+ // place the caret into the new position
+ caret.moveToOffset(offset)
+ }
+ }
+ }
+}
+
+registerAction('Move Caret to Next Word End', 'ctrl NUMPAD6') { AnActionEvent event ->
+ moveCaretToWordEnd(event, 'forward')
+}
+
+registerAction('Move Caret to Previous Word End', 'ctrl NUMPAD4') { AnActionEvent event ->
+ moveCaretToWordEnd(event, 'backward')
+}