diff --git a/.idea/misc.xml b/.idea/misc.xml
index b7dd008f3..9f47cec4b 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 1a0ad7456..a997b0925 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -4,7 +4,6 @@
-
diff --git a/.idea/runConfigurations/editor_basics.xml b/.idea/runConfigurations/editor_basics.xml
deleted file mode 100644
index 9bc65b3ea..000000000
--- a/.idea/runConfigurations/editor_basics.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/code_samples/editor_basics/build.gradle b/code_samples/editor_basics/build.gradle
new file mode 100644
index 000000000..ecf47fa2c
--- /dev/null
+++ b/code_samples/editor_basics/build.gradle
@@ -0,0 +1,31 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+
+plugins {
+ id 'java'
+ id 'org.jetbrains.intellij' version '0.4.9'
+}
+
+group 'org.intellij.sdk'
+version '2.0.0'
+
+sourceCompatibility = 1.8
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ testCompile group: 'junit', name: 'junit', version: '4.12'
+}
+
+// See https://github.com/JetBrains/gradle-intellij-plugin/
+intellij {
+ version '2019.2'
+ updateSinceUntilBuild = false
+}
+patchPluginXml {
+ version = project.version
+}
+
+// Force javadoc rebuild before jar is built
+jar.dependsOn javadoc
diff --git a/code_samples/editor_basics/editor_basics.iml b/code_samples/editor_basics/editor_basics.iml
deleted file mode 100644
index 3700dfbf1..000000000
--- a/code_samples/editor_basics/editor_basics.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/code_samples/editor_basics/gradle/wrapper/gradle-wrapper.jar b/code_samples/editor_basics/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..94336fcae
Binary files /dev/null and b/code_samples/editor_basics/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/code_samples/editor_basics/gradle/wrapper/gradle-wrapper.properties b/code_samples/editor_basics/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..290541c73
--- /dev/null
+++ b/code_samples/editor_basics/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/code_samples/editor_basics/gradlew b/code_samples/editor_basics/gradlew
new file mode 100755
index 000000000..cccdd3d51
--- /dev/null
+++ b/code_samples/editor_basics/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/code_samples/editor_basics/gradlew.bat b/code_samples/editor_basics/gradlew.bat
new file mode 100644
index 000000000..f9553162f
--- /dev/null
+++ b/code_samples/editor_basics/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/code_samples/editor_basics/resources/META-INF/plugin.xml b/code_samples/editor_basics/resources/META-INF/plugin.xml
deleted file mode 100644
index 1f2ca6962..000000000
--- a/code_samples/editor_basics/resources/META-INF/plugin.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
- org.jetbrains.plugins.sample.EditorBasics
- Editor basics
- 1.0
- JetBrains
-
- Illustration of various basic Editor APIs
-
-
- com.intellij.modules.lang
-
-
- com.intellij.modules.lang
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/code_samples/editor_basics/settings.gradle b/code_samples/editor_basics/settings.gradle
new file mode 100644
index 000000000..4efbaacb2
--- /dev/null
+++ b/code_samples/editor_basics/settings.gradle
@@ -0,0 +1,2 @@
+rootProject.name = 'editor'
+
diff --git a/code_samples/editor_basics/src/main/java/icons/EditorBasicsIcons.java b/code_samples/editor_basics/src/main/java/icons/EditorBasicsIcons.java
new file mode 100644
index 000000000..7ab2c4ccb
--- /dev/null
+++ b/code_samples/editor_basics/src/main/java/icons/EditorBasicsIcons.java
@@ -0,0 +1,11 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+
+package icons;
+
+import com.intellij.openapi.util.IconLoader;
+
+import javax.swing.*;
+
+public class EditorBasicsIcons {
+ public static final Icon Sdk_default_icon = IconLoader.getIcon("/icons/sdk_16.svg");
+}
diff --git a/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorAreaIllustration.java b/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorAreaIllustration.java
similarity index 63%
rename from code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorAreaIllustration.java
rename to code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorAreaIllustration.java
index ba3bcd67d..ed2a3b759 100644
--- a/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorAreaIllustration.java
+++ b/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorAreaIllustration.java
@@ -1,4 +1,6 @@
-package org.jetbrains.tutorials.editor.basics;
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+
+package org.intellij.sdk.editor;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.*;
@@ -18,13 +20,18 @@ public class EditorAreaIllustration extends AnAction {
int offset = caretModel.getOffset();
Messages.showInfoMessage(logicalPosition.toString() + "\n" +
visualPosition.toString() + "\n" +
- "Offset: " + offset, "Caret Parameters Inside The Editor");
+ "Offset: " + offset
+ // TODO: Remove the next line of diagnostic code
+ + "\n" + "LogicalPosition.leansForward = " + String.valueOf(logicalPosition.leansForward),
+ "Caret Parameters Inside The Editor");
}
@Override
public void update(AnActionEvent e) {
+ //Get required data keys
final Project project = e.getData(CommonDataKeys.PROJECT);
final Editor editor = e.getData(CommonDataKeys.EDITOR);
+ //Set visibility only in case of existing project and editor
e.getPresentation().setVisible(project != null && editor != null);
}
}
diff --git a/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorHandlerIllustration.java b/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorHandlerIllustration.java
similarity index 87%
rename from code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorHandlerIllustration.java
rename to code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorHandlerIllustration.java
index e668c8295..c63150416 100644
--- a/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorHandlerIllustration.java
+++ b/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorHandlerIllustration.java
@@ -1,4 +1,6 @@
-package org.jetbrains.tutorials.editor.basics;
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+
+package org.intellij.sdk.editor;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Editor;
diff --git a/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorIllustration.java b/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorIllustration.java
similarity index 80%
rename from code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorIllustration.java
rename to code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorIllustration.java
index 37758b7b4..2e0f02a57 100644
--- a/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorIllustration.java
+++ b/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorIllustration.java
@@ -1,4 +1,6 @@
-package org.jetbrains.tutorials.editor.basics;
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+
+package org.intellij.sdk.editor;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.command.WriteCommandAction;
@@ -24,14 +26,15 @@ public class EditorIllustration extends AnAction {
final Project project = e.getRequiredData(CommonDataKeys.PROJECT);
//Access document, caret, and selection
final Document document = editor.getDocument();
+ // Get information about the selection
final SelectionModel selectionModel = editor.getSelectionModel();
-
final int start = selectionModel.getSelectionStart();
final int end = selectionModel.getSelectionEnd();
- //Making the replacement
+ //Make the replacement with the name of this plugin
WriteCommandAction.runWriteCommandAction(project, () ->
- document.replaceString(start, end, "Replacement")
+ document.replaceString(start, end, "Replaced by editor_basics")
);
+ // De-select the text range that was just replaced
selectionModel.removeSelection();
}
diff --git a/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/MyTypedHandler.java b/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/MyTypedHandler.java
similarity index 65%
rename from code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/MyTypedHandler.java
rename to code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/MyTypedHandler.java
index 5a29ef376..3884ca769 100644
--- a/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/MyTypedHandler.java
+++ b/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/MyTypedHandler.java
@@ -1,4 +1,6 @@
-package org.jetbrains.tutorials.editor.basics;
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+
+package org.intellij.sdk.editor;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.command.WriteCommandAction;
@@ -10,17 +12,12 @@ import org.jetbrains.annotations.NotNull;
/**
* @author Anna Bulenkova
*/
-public class MyTypedHandler implements TypedActionHandler {
+class MyTypedHandler implements TypedActionHandler {
@Override
public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext) {
final Document document = editor.getDocument();
Project project = editor.getProject();
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- document.insertString(0, "Typed\n");
- }
- };
+ Runnable runnable = () -> document.insertString(0, "Inserted by editor_basics\n");
WriteCommandAction.runWriteCommandAction(project, runnable);
}
}
diff --git a/code_samples/editor_basics/src/main/resources/META-INF/plugin.xml b/code_samples/editor_basics/src/main/resources/META-INF/plugin.xml
new file mode 100644
index 000000000..16f50416b
--- /dev/null
+++ b/code_samples/editor_basics/src/main/resources/META-INF/plugin.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+ org.intellij.sdk.editor
+
+
+ SDK: Editor Sample Project
+
+
+ 2.0.0
+
+
+
+
+
+ com.intellij.modules.lang
+
+
+
+ Mouse over each of this plugin's menu items to see hints in the lower left corner of the IDE.
+ ]]>
+
+
+
+
2.0.0 Convert to Gradle-based plugin
+
1.0.0 Release 2019.1 and earlier.
+
+ ]]>
+
+
+
+ IntelliJ Platform SDK
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code_samples/editor_basics/src/main/resources/META-INF/pluginIcon.svg b/code_samples/editor_basics/src/main/resources/META-INF/pluginIcon.svg
new file mode 100644
index 000000000..613290897
--- /dev/null
+++ b/code_samples/editor_basics/src/main/resources/META-INF/pluginIcon.svg
@@ -0,0 +1,58 @@
+
diff --git a/code_samples/editor_basics/src/main/resources/icons/sdk_16.svg b/code_samples/editor_basics/src/main/resources/icons/sdk_16.svg
new file mode 100644
index 000000000..011462b8a
--- /dev/null
+++ b/code_samples/editor_basics/src/main/resources/icons/sdk_16.svg
@@ -0,0 +1,7 @@
+
diff --git a/tutorials/editor_basics/coordinates_system.md b/tutorials/editor_basics/coordinates_system.md
index 3adb785fa..f0302cd2e 100644
--- a/tutorials/editor_basics/coordinates_system.md
+++ b/tutorials/editor_basics/coordinates_system.md
@@ -1,20 +1,26 @@
---
-title: 2. Editor coordinates system. Positions and offsets
+title: 2. Editor Coordinate Systems - Positions and Offsets
---
+The previous tutorial [Working with Text](working_with_text.md) discussed extending the [AnAction.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java) class, and using an [AnActionEvent](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) object.
+The event object provides access to [Project](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java), [Document](upsource:///platform/core-api/src/com/intellij/openapi/editor/Document.java), and [Editor](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/Editor.java) objects.
-Every caret in the editor has a set of properties describing its coordinates.
-These properties can be accessed by obtaining a
-[caret model instance](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java).
-Working with caret positions and their logical and visual properties will be explained in the sample below.
+Every caret has a set of properties describing its position in one of several coordinate systems.
+This tutorial describes how to access information about the caret(s) in the editor.
## 2.1. Pre-requirements
-Access to the Editor is performed through an action.
+In this tutorial the [editor_basics](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/editor_basics) code sample is used to explore caret positions.
+In particular, the **Caret Position** action added by `editor_basics` to the editor context menu is used to retrieve information about the current caret position.
-## 2.2. Accessing caret positions
+{:width="600px"}
-To get an access to caret positions an instance of `CaretModel` should be obtained.
+The source code for the Java class behind the menu action is [EditorAreaIllustration.java](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorAreaIllustration.java).
+The focus of discussion will be the `EditorAreaIllustration.actionPerformed()` method.
+## 2.2. Accessing Caret Positions from the CaretModel Object
+The properties of a caret can be accessed by obtaining an instance of the [CaretModel](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java) object for a caret.
+As in the [Working with Text](working_with_text.md) tutorial, the `AnActionEvent` is used to get the `Editor` object.
+The `Editor` object provides access to the `CaretModel` object, as shown below:
```java
public class EditorAreaIllustration extends AnAction {
@Override
@@ -23,18 +29,45 @@ public class EditorAreaIllustration extends AnAction {
CaretModel caretModel = editor.getCaretModel();
}
@Override
- public void update(AnActionEvent e) {
- //...
- }
+ public void update(AnActionEvent e) { /* ... */ }
}
```
-## 2.3. Logical position
+## 2.3. Caret Position
+When a Document is opened the editor assigns an internal, zero-based coordinate system to lines and columns in the Document.
+The first line in a Document and the first character in each line are assigned the zero position.
+Note that the editor coordinate system is different from what is shown in the editor UI, which is one-based rather than zero-based.
-[LogicalPosition.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/LogicalPosition.java)
-represents a line and a column of the current logical position of the caret. Logical positions ignore folding —
-for example, if the top 10 lines of the document are folded, the 10th line in the document will have the line number 10 in its logical position.
+[//]: # (TODO: Mention multiple carets, primary carets, single caret in Editor = primary caret)
+### 2.3.1. Caret Logical Position
+The caret _Logical Position_ is a zero-based, (line and column) position of the caret in the Editor Tool Window.
+Line values are based on the corresponding lines in the underlying Document being edited.
+Logical Position information is obtained from the [LogicalPosition](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/LogicalPosition.java) object for that caret.
+
+The Logical Position line number of a caret ignores the effects of settings that change the presentation of a Document within the Editor Tool Window.
+Examples of these settings are [Code (Line) Folding](https://www.jetbrains.com/help/idea/working-with-source-code.html#code_folding) and [Soft Line Wrap](https://www.jetbrains.com/help/idea/using-code-editor.html#f804afd8).
+This means regardless of whether one or more lines in an Editor Tool Window are folded or soft-wrapped, the caret Logical Position line number will not change.
+
+The image below shows the simplest case of reporting Logical Position using the caret position functionality of the `editor_basics` plugin.
+No Soft Wrap or Code Folding is applied.
+Each line has a comment showing the Logical Position line number.
+The caret - a blue block - is placed on the letter "p" in "public".
+The caret is reported to be at Logical Position (5,0) - which is Logical (Position) line 5, character 0 - the first character in the line.
+[Caret Visual Position](#232-caret-visual-position), [caret leaning,](#233-caret-column-position), and [caret offset](#234-caret-offset) are discussed in later sections.
+
+{:width="800px"}
+
+If Logical Position line numbers 1-3 are folded into line 0, the caret is still reported as Logical Position (5,0).
+This means that caret Logical Position is not changed by Code Folding:
+
+{:width="800px"}
+
+However, note that applying Code Folding _does change the reported Visual Position_ of the caret even if the Logical Position stays constant.
+More about [Visual Position](#232-caret-visual-position) is discussed below, but it's clear combinations of Code Folding and Soft Wrap can mean that one Logical Position of a caret could map to multiple Visual Positions.
+It is for this reason the Editor interface provides a number of methods to work with a caret Logical and Visual Position, such as the method `Editor.logicalToVisualPosition()`.
+
+The `LogicalPosition` object for a caret is obtained from the caret's `CaretModel`object, as shown in the code snippet below.
```java
public class EditorAreaIllustration extends AnAction {
@Override
@@ -44,25 +77,26 @@ public class EditorAreaIllustration extends AnAction {
LogicalPosition logicalPosition = caretModel.getLogicalPosition();
}
@Override
- public void update(AnActionEvent e) {
- //...
- }
+ public void update(AnActionEvent e) { /* ... */ }
}
```
-Logical position may store additional parameters that define its mapping to
-[VisualPosition.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/VisualPosition.java).
-Rationale is that a single logical pair matches a virtual space introduced by soft wrap, i.e. different visual positions
-may correspond to the same logical position. It's convenient to store exact visual location details within the logical
-position in order to simplify further 'logical position' -> 'visual position' mapping.
+### 2.3.2. Caret Visual Position
+A caret's _Visual Position_ differs from Logical Position in that it takes into account editor presentation settings such as Code Folding and Soft Line Wrap.
+In doing so, [VisualPosition](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/VisualPosition.java) counts - zero-based - the lines of a Document that are _displayed_ in an editor Tool Window.
+Consequently, Visual Position lines are not uniquely mapped to corresponding lines in the underlying Document being edited.
-## 2.4. Visual position
+For example, when Soft Line Wrap is applied to a line displayed in an Editor Tool Window it affects the Visual Position.
+In the image below, Soft Line Wrap has been applied to Logical line three.
+With the caret placed at the same location as in previous tests, it is evident the Logical Position has not changed.
+However, the Visual Position line number has increased by 1!
+The comments on each line illustrate how the Soft Wrap portion of Editor Line three is considered Visual Position line four, as though it was a separate line.
-[VisualPosition.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/VisualPosition.java)
-represents a visual position and may differ from the corresponding logical position.
-Visual positions take folding into account — for example,
-if the top 10 lines of the document are folded, the 10th line in the document will have the line number 1 in its visual position.
+{:width="800px"}
+The Editor interface provides a number of methods to work with a caret Logical and Visual Position, such as the method `Editor.visualToLogicalPosition()`.
+
+The Visual Position object for a caret is obtained from the caret's `CaretModel` object, as shown in the code snippet below.
```java
public class EditorAreaIllustration extends AnAction {
@Override
@@ -73,16 +107,58 @@ public class EditorAreaIllustration extends AnAction {
VisualPosition visualPosition = caretModel.getVisualPosition();
}
@Override
- public void update(AnActionEvent e) {
- //...
- }
+ public void update(AnActionEvent e) { /* ... */ }
}
```
-## 2.5. Offset
+### 2.3.3. Caret Column Position
+The _Column Position_ is a count of characters from the beginning of a Logical (Position) line to the current caret position in that line.
+Characters are counted using a zero-based numbering system, so the first character of a line is numbered zero.
+Note that Column Position is different from what is shown in the editor UI, which uses a one-based numbering scheme.
-An absolute offset for a given caret position is accessible through `CaretModel` as well:
+Column Position includes:
+* The first character in a Logical line.
+* Whitespace, such as tabs.
+ Tabs can occupy multiple columns, up to the tab size set for the editor.
+* The character selected by the caret.
+More specifically, the Logical Position of a caret represents the boundary between two characters.
+As defined in the [LogicalPosition](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/LogicalPosition.java) class, if a caret position is associated with a succeeding character it is said to _Lean Forward_.
+
+[//]: # (TODO: Add an understandable definition for characters leaning forward. BOL leans, just before "space" does not.)
+
+In the example below, placing a (red) line caret on the first visible character in Logical line three produces a **complete lack of lean forward?!**
+**Only with caret color #FF0000 ?! The same color as for 'Unknown Symbol' in my Preferences \| Editor \| Color Scheme \| General**
+
+[//]: # (TODO: Why does this not work for red line caret?)
+
+{:width="800px"}
+
+In the example below, placing a (blue) block caret on the first visible character in Logical line three produces a column position of 0 for both Visual and Logical Positions.
+In both Visual and Logical Positions the character leans forward, meaning it is associated with the succeeding character in the Logical line.
+
+[//]: # (TODO: Why does this seem to always return leans forward for a block caret?)
+
+{:width="800px"}
+
+
+### 2.3.4. Caret Offset
+The _Offset_ of a caret is a character count from the beginning of a Document to the caret position.
+Caret offsets are always calculated in terms of Logical Position.
+The caret Offset includes:
+* The first (0th) character in a document.
+* Whitespace characters, including end-of-line and tabs.
+* Any characters after end-of-line if the IDE settings permit them.
+ (**Preferences \| Editor \| General \| Virtual Space**)
+* The character selected by the caret.
+
+The example below demonstrates the Offset of a caret placed at the first character of Logical line one.
+Note the Offset is 22, which is 1 greater than the number of visible characters on line one, and the first character on line two.
+This is because the Offset includes the EOL character for the first line.
+
+{:width="800px"}
+
+The Offset for a given caret position is accessible through `CaretModel` as well:
```java
public class EditorAreaIllustration extends AnAction {
@Override
@@ -94,15 +170,14 @@ public class EditorAreaIllustration extends AnAction {
int offset = caretModel.getOffset();
}
@Override
- public void update(AnActionEvent e) {
- //...
- }
-}
+ public void update(AnActionEvent e) { /* ... */ }
+ }
```
-## 2.6. Displaying position values
-To display the actual values of logical and visual positions we add an
-`Messages.showInfoMessage()` call that will show them in form of notification after the action is performed.
+
+## 2.4. Displaying position values
+To display the actual values of logical and visual positions an
+`Messages.showInfoMessage()` call shows them in form of notification after the action is performed.
```java
public class EditorAreaIllustration extends AnAction {
@@ -118,28 +193,9 @@ public class EditorAreaIllustration extends AnAction {
"Offset: " + offset, "Caret Parameters Inside The Editor");
}
@Override
- public void update(AnActionEvent e) {
- //...
- }
+ public void update(AnActionEvent e) { /* ... */ }
}
```
-Check out, compile, and run the
-[Editor Basics Plugin](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/editor_basics),
-then move carets, invoke
-[EditorAreaIllustration](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorAreaIllustration.java)
-action, and see how logical and visual positions are related dependently on folding.
-
-Find the action in the context menu:
-
-
-
-Perform the action to see caret positions:
-
-
-
-
-
-
-
+[//]: # (TODO: Add section with hints for reader to work with multiple carets.)
diff --git a/tutorials/editor_basics/img/basics.png b/tutorials/editor_basics/img/basics.png
index bfedd46e2..e341bfab2 100644
Binary files a/tutorials/editor_basics/img/basics.png and b/tutorials/editor_basics/img/basics.png differ
diff --git a/tutorials/editor_basics/img/caret_col_pos_block.png b/tutorials/editor_basics/img/caret_col_pos_block.png
new file mode 100644
index 000000000..f512452c7
Binary files /dev/null and b/tutorials/editor_basics/img/caret_col_pos_block.png differ
diff --git a/tutorials/editor_basics/img/caret_col_pos_line.png b/tutorials/editor_basics/img/caret_col_pos_line.png
new file mode 100644
index 000000000..597dea531
Binary files /dev/null and b/tutorials/editor_basics/img/caret_col_pos_line.png differ
diff --git a/tutorials/editor_basics/img/caret_offset_l2.png b/tutorials/editor_basics/img/caret_offset_l2.png
new file mode 100644
index 000000000..4b64f206d
Binary files /dev/null and b/tutorials/editor_basics/img/caret_offset_l2.png differ
diff --git a/tutorials/editor_basics/img/coordinates_action.png b/tutorials/editor_basics/img/coordinates_action.png
deleted file mode 100644
index 596396948..000000000
Binary files a/tutorials/editor_basics/img/coordinates_action.png and /dev/null differ
diff --git a/tutorials/editor_basics/img/coordinates_demo.png b/tutorials/editor_basics/img/coordinates_demo.png
deleted file mode 100644
index e89e154c5..000000000
Binary files a/tutorials/editor_basics/img/coordinates_demo.png and /dev/null differ
diff --git a/tutorials/editor_basics/img/edit_basics_menu.png b/tutorials/editor_basics/img/edit_basics_menu.png
new file mode 100644
index 000000000..54ac1cb37
Binary files /dev/null and b/tutorials/editor_basics/img/edit_basics_menu.png differ
diff --git a/tutorials/editor_basics/img/logical_pos_exp.png b/tutorials/editor_basics/img/logical_pos_exp.png
new file mode 100644
index 000000000..e37cc588a
Binary files /dev/null and b/tutorials/editor_basics/img/logical_pos_exp.png differ
diff --git a/tutorials/editor_basics/img/logical_pos_folded.png b/tutorials/editor_basics/img/logical_pos_folded.png
new file mode 100644
index 000000000..8e523b2b0
Binary files /dev/null and b/tutorials/editor_basics/img/logical_pos_folded.png differ
diff --git a/tutorials/editor_basics/img/vis_pos_soft_wrap.png b/tutorials/editor_basics/img/vis_pos_soft_wrap.png
new file mode 100644
index 000000000..064507006
Binary files /dev/null and b/tutorials/editor_basics/img/vis_pos_soft_wrap.png differ
diff --git a/tutorials/editor_basics/working_with_text.md b/tutorials/editor_basics/working_with_text.md
index 37e70f61f..fc6ea9dba 100644
--- a/tutorials/editor_basics/working_with_text.md
+++ b/tutorials/editor_basics/working_with_text.md
@@ -4,47 +4,45 @@ title: 1. Working with text
The following set of steps will show how to access a text selection and change it.
+## 1.1. Introduction
+This tutorial relies heavily on the [editor_basics](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/editor_basics/) plugin code sample from the IntelliJ Platform SDK.
+It may be helpful to open that project in an IntelliJ Platform-based IDE, build the project, run it, select some text in the editor, and invoke the "Editor Replace Text" menu item on the editor context menu.
-## 1.1. Pre-requirements
+-----------
-### 1.1.1 Creating a new action
+{:width="600px"}
-In this example we access the editor from an action.
-To create an action we need to extend the
-[AnAction.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java)
-class.
+-----------
+### 1.1.1 Creating a New action
+The source code for the Java class in this example is [EditorIllustration.java](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/editor_basics/src/main/java/org/intellij/sdk/editor/EditorIllustration.java).
+In this example, we access the editor from an action.
+To create an action we need to extend the [AnAction.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java) class.
```java
public class EditorIllustration extends AnAction {
}
```
-
-### 1.1.2. Registering an action
-
-To register the action we should add the corresponding tag to the `` section of the plugin configuration file
-[plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/editor_basics/resources/META-INF/plugin.xml)
-
-
+### 1.1.2. Registering an Action
+To register the action, we should add the corresponding elements to the `` section of the plugin configuration file
+[plugin.xml](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/editor_basics/src/main/resources/META-INF/plugin.xml)
```xml
-
-
-
+
+
-
```
-If an action is registered in the group `EditorPopupMenu`, like the sample above shows,
+If an action is registered in the group `EditorPopupMenu`, as the sample above shows,
it will be available from the context menu when the focus is located in the editor.
-
-### 1.1.3. Defining action's visibility
-
+### 1.1.3. Defining Action's Visibility
To determine conditions by which the action will be visible and available for being executed we need to override its
`public void update(AnActionEvent e)` method.
-
```java
public class EditorIllustration extends AnAction {
@Override
@@ -54,19 +52,15 @@ public class EditorIllustration extends AnAction {
```
If we want to work with a selected part of the text, it's reasonable to make the action available only when the following requirements are met:
+* There is a [Project](upsource:///platform/core-api/src/com/intellij/openapi/project/Project.java) object,
+* There is an instance of [Editor](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/Editor.java) available,
+* There is a text selection in `Editor`.
-* There is a project open
-* There is an instance of the Editor available
-* There is a text selection in the Editor
-
-Further steps will show how to check these conditions through obtaining instances of Project and Editor and how to show or hide the action based on them.
-
-## 1.2. Getting an instance of the active Editor
-
-A reference to an instance of the Editor can be obtained by calling `getData(CommonDataKeys.EDITOR)`.
-To obtain a project reference, we use the `getProject()` method.
-
+Further steps will show how to check these conditions through obtaining instances of `Project` and `Editor` objects, and how to show or hide the action's menu items based on them.
+## 1.2. Getting an Instance of the Active Editor from an Event
+Using the [AnActionEvent](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java) event passed into the `update` method, a reference to an instance of the editor can be obtained by calling `getData(CommonDataKeys.EDITOR)`.
+Similarly, to obtain a project reference, we use the `getProject()` method.
```java
public class EditorIllustration extends AnAction {
@Override
@@ -74,30 +68,24 @@ public class EditorIllustration extends AnAction {
//Get required data keys
final Project project = e.getProject();
final Editor editor = e.getData(CommonDataKeys.EDITOR);
- //Set visibility only in case of existing project and editor
+ //Set visibility only in case of existing project and editor (for now, selection is added below)
e.getPresentation().setVisible(project != null && editor != null);
}
}
```
-**Note:**
-
-To access an Editor instance, other ways can also be used:
-
-* If [DataContext](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/DataContext.java)
- object is available: `final Editor editor = CommonDataKeys.EDITOR.getData(context);`
-
-* If only a `Project` is available, you can use `FileEditorManager.getInstance(project).getSelectedTextEditor()`
+**Note:**
+There are other ways to access an `Editor` instance:
+* If a [DataContext](upsource:///platform/editor-ui-api/src/com/intellij/openapi/actionSystem/DataContext.java) object is available: `final Editor editor = CommonDataKeys.EDITOR.getData(context);`
+* If only a `Project` object is available, use `FileEditorManager.getInstance(project).getSelectedTextEditor()`
-## 1.3. Obtaining a caret model and selection
-
-After making sure we have a project open and an instance of the Editor we need to check if any selection is available and set action's visibility according to these conditions.
-[SelectionModel](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/SelectionModel.java)
-accessed from the Editor allows to do it by calling its `hasSelection()` method.
+## 1.3. Obtaining a Caret Model and Selection
+After making sure a project is open and an instance of the editor is obtained, we need to check if any selection is available.
+The [SelectionModel](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/SelectionModel.java) interface is accessed from the `Editor` object.
+Determining whether some text is selected is accomplished by calling the `hasSelection()` method.
Here's how our `update(AnActionEvent e)` method should look like in the end:
-
```java
public class EditorIllustration extends AnAction {
@Override
@@ -105,21 +93,17 @@ public class EditorIllustration extends AnAction {
//Get required data keys
final Project project = e.getProject();
final Editor editor = e.getData(CommonDataKeys.EDITOR);
- //Set visibility only in case of existing project and editor and if some text in the editor is selected
- e.getPresentation().setVisible(project != null && editor != null &&
- editor.getSelectionModel().hasSelection());
+ //Set visibility only in case of the existence of a project, editor, and if text is selected in the editor
+ e.getPresentation().setVisible( project != null
+ && editor != null
+ && editor.getSelectionModel().hasSelection() );
}
}
```
**Note:**
-Editor allows to access different models of text representation.
-Model classes are located in
-[editor](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor)
-subpackage of the
-[editor-ui-api](upsource:///platform/editor-ui-api)
-package and include:
-
+`Editor` also allows access to different models of text representation.
+The model classes are located in [editor](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor), and include:
* [CaretModel.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java),
* [FoldingModel.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/FoldingModel.java),
* [IndentsModel.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/IndentsModel.java),
@@ -127,32 +111,21 @@ package and include:
* [SoftWrapModel.java](upsource:///platform/editor-ui-api/src/com/intellij/openapi/editor/SoftWrapModel.java)
-## 1.4. Obtaining a Document
-
-The action is visible and available now.
-In order to make it do something we need to override its
-`public void actionPerformed(AnActionEvent anActionEvent)` method.
-
-
+## 1.4. Obtaining the Document
+The `EditorIllustration` action menu item is visible and available now.
+To make it do something we need to override its `actionPerformed()` method.
```java
public class EditorIllustration extends AnAction {
- @Override
- public void update(AnActionEvent e) {
- //code here
- }
@Override
public void actionPerformed(AnActionEvent anActionEvent) {
}
}
```
-To modify the text an instance of the
-[Document](upsource:///platform/core-api/src/com/intellij/openapi/editor/Document.java)
-needs to be accessed. [Document](/basics/architectural_overview/documents.md) represents the contents of a text file loaded into memory and possibly opened in an IDEA text editor.
+Modifying the text requires an instance of the [Document](upsource:///platform/core-api/src/com/intellij/openapi/editor/Document.java) object, which is accessed from the `Editor` object.
+The [Document](/basics/architectural_overview/documents.md) represents the contents of a text file loaded into memory and possibly opened in an IDEA text editor.
The instance of a Document will be used later when a text replacement is performed.
-We also need to figure out where the selected part of the text is located.
-
-
+We also need to figure out where the selected part of the text is located in the document.
```java
@Override
public void actionPerformed(final AnActionEvent e) {
@@ -167,14 +140,11 @@ public void actionPerformed(final AnActionEvent e) {
}
```
-## 1.5. Modifying text
-
-Generally replacement can be done by calling
-`void replaceString(int startOffset, int endOffset, @NotNull CharSequence s);` of the Document, however,
-the operation of replacement must be executed safely, this means the Document must be locked and
-any changes should be performed in a [write action](upsource:///platform/core-api/src/com/intellij/openapi/command/WriteCommandAction.java).
+## 1.5. Modifying Text
+Generally, text replacement can be done by calling the `Document` object's `replaceString()` method.
+However, safely replacing the text requires the Document to be locked and any changes performed in a [write action](upsource:///platform/core-api/src/com/intellij/openapi/command/WriteCommandAction.java).
See the [Threading Issues](/basics/architectural_overview/general_threading_rules.md) section to learn more about synchronization issues and changes safety on the IntelliJ Platform.
-
+This example changes the document within a `WriteCommandAction`.
```java
@Override
public void actionPerformed(final AnActionEvent e) {
@@ -183,26 +153,17 @@ public void actionPerformed(final AnActionEvent e) {
final Project project = e.getProject();
//Access document, caret, and selection
final Document document = editor.getDocument();
+ // Get information about the selection
final SelectionModel selectionModel = editor.getSelectionModel();
-
final int start = selectionModel.getSelectionStart();
final int end = selectionModel.getSelectionEnd();
- //Making the replacement
+ //Make the replacement
WriteCommandAction.runWriteCommandAction(project, () ->
document.replaceString(start, end, "Replacement")
);
+ // Deselect the replaced text
selectionModel.removeSelection();
}
```
------------
-
-
------------
-
-The source code is located in
-[EditorIllustration.java](https://github.com/JetBrains/intellij-sdk-docs/blob/master/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/EditorIllustration.java).
-To see how text replacement works, check out
-[Editor Basics](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/editor_basics/src/org/jetbrains/tutorials/editor/basics/)
-plugin, make the project, run it, then invoke the *EditorIllustration* action which is available in the context menu of the editor.