Convert Code Assistance lessons from XML to Kotlin DSL, update these lessons and...
authorKonstantin Hudyakov <konstantin.hudyakov@jetbrains.com>
Wed, 23 Sep 2020 10:37:30 +0000 (13:37 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Wed, 23 Sep 2020 10:53:52 +0000 (10:53 +0000)
Add Code Assistance lessons for Python and Ruby

GitOrigin-RevId: dc1d84cd7ffdbeeb0fd1e1be970b297e9cbd9a7c

34 files changed:
ide-features-trainer/res/META-INF/javascript-deps.xml
ide-features-trainer/res/META-INF/python-deps.xml
ide-features-trainer/res/META-INF/ruby-deps.xml
ide-features-trainer/res/data/modules/java/CodeAssistance.xml
ide-features-trainer/res/data/modules/java/CodeAssistance/02.CodeFormat.xml [deleted file]
ide-features-trainer/res/data/modules/java/CodeAssistance/03.ParameterInfo.xml [deleted file]
ide-features-trainer/res/data/modules/java/CodeAssistance/04.QuickPopups.xml [deleted file]
ide-features-trainer/res/data/modules/java/CodeAssistance/05.EditorCodingAssistance.xml [deleted file]
ide-features-trainer/res/data/modules/java/CodeAssistance/CodeFormat.java.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/java/CodeAssistance/EditorCodingAssistance.java.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/java/CodeAssistance/ParameterInfo.java.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/java/CodeAssistance/QuickPopups.java.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/python/CodeAssistance.xml [new file with mode: 0644]
ide-features-trainer/res/data/modules/python/CodeAssistance/CodeFormat.py.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/python/CodeAssistance/EditorCodingAssistance.py.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/python/CodeAssistance/ParameterInfo.py.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/python/CodeAssistance/QuickPopups.py.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/ruby/CodeAssistance.xml [new file with mode: 0644]
ide-features-trainer/res/data/modules/ruby/CodeAssistance/CodeFormat.rb.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/ruby/CodeAssistance/EditorCodingAssistance.rb.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/ruby/CodeAssistance/ParameterInfo.rb.sample [new file with mode: 0644]
ide-features-trainer/res/data/modules/ruby/CodeAssistance/QuickPopups.rb.sample [new file with mode: 0644]
ide-features-trainer/res/messages/LessonsBundle.properties
ide-features-trainer/src/training/check/CheckParameterInfo.kt [deleted file]
ide-features-trainer/src/training/check/CheckQuickPopupsQuickDoc.kt [deleted file]
ide-features-trainer/src/training/check/CheckReaderClose.kt [deleted file]
ide-features-trainer/src/training/check/CheckTryFinally.kt [deleted file]
ide-features-trainer/src/training/learn/lesson/general/assistance/CodeFormatLesson.kt [new file with mode: 0644]
ide-features-trainer/src/training/learn/lesson/general/assistance/EditorCodingAssistanceLesson.kt [new file with mode: 0644]
ide-features-trainer/src/training/learn/lesson/general/assistance/ParameterInfoLesson.kt [new file with mode: 0644]
ide-features-trainer/src/training/learn/lesson/general/assistance/QuickPopupsLesson.kt [new file with mode: 0644]
ide-features-trainer/src/training/learn/lesson/java/assistance/JavaEditorCodingAssistanceLesson.kt [new file with mode: 0644]
ide-features-trainer/src/training/learn/lesson/python/assistance/PythonEditorCodingAssistanceLesson.kt [new file with mode: 0644]
ide-features-trainer/src/training/learn/lesson/ruby/assistance/RubyEditorCodingAssistanceLesson.kt [new file with mode: 0644]

index ab8498aa4b2db72a90ee9b5d34afe184c024df67..2c65e726a2a9efcbf392bb042d62070d43925b38 100644 (file)
@@ -5,6 +5,7 @@
 
     <ift.modules language="JavaScript">
       <module path="modules/javascript/EditorBasics.xml"/>
+      <module path="modules/javascript/WebStormDebugger.xml"/>
       <module path="modules/javascript/WebStormTesting.xml"/>
     </ift.modules>
   </extensions>
index 6df4482d8348188fc23f2d25655696e393bf1fa8..9f2a95b735f9337c07d0cc1617583eff7061b1c6 100644 (file)
@@ -6,6 +6,7 @@
       <module path="modules/python/News.xml"/>
       <module path="modules/python/EditorBasics.xml"/>
       <module path="modules/python/Completions.xml"/>
+      <module path="modules/python/CodeAssistance.xml"/>
       <module path="modules/python/Navigation.xml"/>
       <module path="modules/python/Refactorings.xml"/>
       <module path="modules/python/Run.xml"/>
index 86642566ae0088f623fdf64e2eb24bf68582b612..290b93f8d3a5c550315c5b8ae045bad626ff4aa4 100644 (file)
@@ -8,6 +8,7 @@
       <module path="modules/ruby/Navigation.xml"/>
       <module path="modules/ruby/Completions.xml"/>
       <module path="modules/ruby/Refactorings.xml"/>
+      <module path="modules/ruby/CodeAssistance.xml"/>
     </ift.modules>
   </extensions>
 </idea-plugin>
index 7930f470d9475a5fd0a8a310fd080255b2c4674b..f04002e71a2b427a1f5b01e501c16e95192048ae 100755 (executable)
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module name="Code Assistance" lessonsPath="CodeAssistance/" version="0.3" id="code_assistance" fileType="PROJECT" description="Code format, parameter info and quick popups">
   <!--<lesson filename="01.Folding.xml" />-->
-  <lesson filename="02.CodeFormat.xml" />
-  <lesson filename="03.ParameterInfo.xml" />
-  <lesson filename="04.QuickPopups.xml" />
-  <lesson filename="05.EditorCodingAssistance.xml" />
+  <lesson-kt sample="CodeFormat.java.sample" implementationClass="training.learn.lesson.general.assistance.CodeFormatLesson" lang="JAVA"/>
+  <lesson-kt sample="ParameterInfo.java.sample" implementationClass="training.learn.lesson.general.assistance.ParameterInfoLesson" lang="JAVA"/>
+  <lesson-kt sample="QuickPopups.java.sample" implementationClass="training.learn.lesson.general.assistance.QuickPopupsLesson" lang="JAVA"/>
+  <lesson-kt sample="EditorCodingAssistance.java.sample" implementationClass="training.learn.lesson.java.assistance.JavaEditorCodingAssistanceLesson" lang="JAVA"/>
 </module>
 
diff --git a/ide-features-trainer/res/data/modules/java/CodeAssistance/02.CodeFormat.xml b/ide-features-trainer/res/data/modules/java/CodeAssistance/02.CodeFormat.xml
deleted file mode 100755 (executable)
index ac25a89..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<xml type="Scenario" name="Code formatting" id="CodeAssistance.CodeFormatting" lang="JAVA">
-        <CopyText><![CDATA[class CodeFormatDemo{
-
-    final static int a_const = 10000;
-    final static int b_const = 500;
-
-
-public static void calc(){InnerCalc.process(a_const, b_const); }
-
-    static class InnerCalc{
-
-final static int some_const = 124136; public static int process(int a, int b){ return  a * b + some_const;
-        }
-    }
-
-}]]></CopyText>
-    <SetSelection start-position="7:1" end-position="7:65" />
-    <Try triggers="ReformatCode"><ide/> can help you correct code formatting with just one action. Try reformatting the selected code with <action>ReformatCode</action>.</Try>
-    <Try triggers="ReformatCode">To reformat the whole source file, use <action>ReformatCode</action> when no lines are selected.</Try>
-    <Win/>
-</xml>
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/java/CodeAssistance/03.ParameterInfo.xml b/ide-features-trainer/res/data/modules/java/CodeAssistance/03.ParameterInfo.xml
deleted file mode 100755 (executable)
index 95ff438..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<xml type="Scenario" name="Parameter info" id="CodeAssistance.ParameterInfo" lang="JAVA">
-    <MouseBlock><CopyText><![CDATA[import javax.swing.*;
-
-class FrameDemo {
-
-    public static void main(String[] args) {
-        JFrame frame = new JFrame("FrameDemo");
-        frame.setSize();
-
-        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
-        frame.setVisible(true);
-    }
-}]]></CopyText>
-</MouseBlock>
-        <MoveCaret position="7:23" />
-        <Try trigger="ParameterInfo">Press <action>ParameterInfo</action> to see the method signature.</Try>
-        <Try check="training.check.CheckParameterInfo">Use a width of <strong>175</strong> and a height of <strong>100</strong>.</Try>
-    <Win/>
-</xml>
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/java/CodeAssistance/04.QuickPopups.xml b/ide-features-trainer/res/data/modules/java/CodeAssistance/04.QuickPopups.xml
deleted file mode 100755 (executable)
index ef426a2..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<xml type="Scenario" name="Quick popups" id="CodeAssistance.QuickPopups" lang="JAVA">
-    <MouseBlock><CopyText><![CDATA[import java.text.*;
-
-class DecimalFormatDemo {
-    static public void main(String[] args) {
-        customFormat("###,###.###", 123456.789);
-        customFormat("###.##", 123456.789);
-        customFormat("000000.000", 123.78);
-        customFormat("$###,###.###", 12345.67);
-    }
-
-    /**
-     * Prints a double value formatted according to a given pattern.
-     */
-    static public void customFormat(String pattern, double value) {
-        DecimalFormat myFormatter = new DecimalFormat(pattern);
-        String output = myFormatter.format(value);
-        System.out.println(value + "  " + pattern + "  " + output);
-    }
-}]]></CopyText>
-</MouseBlock>
-        <MoveCaret position="5:9" />
-        <Try trigger="QuickJavaDoc">Press <action>QuickJavaDoc</action> to see documentation for the symbol at the caret.</Try>
-        <Try check="training.check.CheckQuickPopupsQuickDoc">Press <action>EditorEscape</action> to close the popup.</Try>
-        <Try trigger="QuickImplementations">Press <action>QuickImplementations</action> to see the definition of the symbol at the caret.</Try>
-    <Win/>
-</xml>
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/java/CodeAssistance/05.EditorCodingAssistance.xml b/ide-features-trainer/res/data/modules/java/CodeAssistance/05.EditorCodingAssistance.xml
deleted file mode 100755 (executable)
index 28cabc7..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<xml type="Scenario" name="Editor coding assistance" id="CodeAssistance.EditorCodingAssistance" lang="JAVA">
-    <MouseBlock><CopyText><![CDATA[import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-class CodeAssistance {
-
-    public static final String EXT = "txt";
-
-    public static void main(String[] args) throws FileNotFoundException {
-        FileReader fileReader = new FileReader("input." + EXT);
-        BufferedReader reader = new BufferedReader(fileReader);
-        ArrayList<String> lines = new ArrayList<String>();
-        String line;
-        while ((line = reader.readLine()) != null) {
-            lines.add(line);
-        }
-        String[] array = lines.toArray(new String[lines.size()]);
-        Arrays.sort(array);
-        for (String s : array) System.out.println(s);
-    }
-}]]></CopyText>
-</MouseBlock>
-        <MoveCaret position="1:1" />
-        <Try trigger="GotoNextError">Press <action>GotoNextError</action> to go to the next highlighted error in the file.</Try>
-        <Try trigger="ShowErrorDescription">Press <action>ShowErrorDescription</action> to see the error description.</Try>
-        <Try trigger="ShowIntentionActions" check="training.check.CheckException">Press <action>ShowIntentionActions</action> and select <strong>Add exception to method signature</strong>.</Try>
-        <SetSelection start-string="BufferedReader reader" end-string="System.out.println(s);"/>
-        <Try trigger="SurroundWith" check="training.check.CheckTryFinally">Press <action>SurroundWith</action> and select <code>try/finally</code> to surround it with the selection.</Try>
-        <Try check="training.check.CheckReaderClose">Close the reader in the <code>finally</code> block by writing <code>fileReader.close()</code></Try>
-        <MoveCaret string="lines"/>
-        <Try trigger="HighlightUsagesInFile">Press <action>HighlightUsagesInFile</action> to highlight all usages of the symbol at the caret within the file.</Try>
-    <Win/>
-</xml>
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/java/CodeAssistance/CodeFormat.java.sample b/ide-features-trainer/res/data/modules/java/CodeAssistance/CodeFormat.java.sample
new file mode 100644 (file)
index 0000000..cf241f8
--- /dev/null
@@ -0,0 +1,19 @@
+import java.util.List;
+import java.util.Set;
+import java.util.ArrayList;
+
+class CodeFormatDemo{
+
+    final static int a_const = 10000;
+    final static int b_const = 500;
+
+
+<select>public static void calc(){InnerCalc.process(a_const, b_const); }</select>
+
+    static class InnerCalc{
+
+final static int some_const = 124136; public static int process(int a, int b){ return  a * b + some_const;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/java/CodeAssistance/EditorCodingAssistance.java.sample b/ide-features-trainer/res/data/modules/java/CodeAssistance/EditorCodingAssistance.java.sample
new file mode 100644 (file)
index 0000000..6fd9918
--- /dev/null
@@ -0,0 +1,23 @@
+<caret>import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class CodeAssistance {
+
+    public static final String EXT = "txt";
+
+    public static void main(String[] args) throws FileNotFoundException {
+        FileReader fileReader = new FileReader("input." + EXT);
+        BufferedReader reader = new BufferedReader(fileReader);
+        ArrayList<String> lines = new ArrayList<String>();
+        String line;
+        while ((line = reader.readLine()) != null) {
+            lines.add(line);
+        }
+        String[] array = lines.toArray(new String[lines.size()]);
+        Arrays.sort(array);
+        for (String s : array) System.out.println(s);
+    }
+}
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/java/CodeAssistance/ParameterInfo.java.sample b/ide-features-trainer/res/data/modules/java/CodeAssistance/ParameterInfo.java.sample
new file mode 100644 (file)
index 0000000..1dde1b5
--- /dev/null
@@ -0,0 +1,12 @@
+import javax.swing.*;
+
+class FrameDemo {
+
+    public static void main(String[] args) {
+        JFrame frame = new JFrame("FrameDemo");
+        frame.setSize(<caret>);
+
+        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+        frame.setVisible(true);
+    }
+}
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/java/CodeAssistance/QuickPopups.java.sample b/ide-features-trainer/res/data/modules/java/CodeAssistance/QuickPopups.java.sample
new file mode 100644 (file)
index 0000000..3aa7c87
--- /dev/null
@@ -0,0 +1,19 @@
+import java.text.*;
+
+class DecimalFormatDemo {
+    static public void main(String[] args) {
+        <caret>customFormat("###,###.###", 123456.789);
+        customFormat("###.##", 123456.789);
+        customFormat("000000.000", 123.78);
+        customFormat("$###,###.###", 12345.67);
+    }
+
+    /**
+     * Prints a double value formatted according to a given pattern.
+     */
+    static public void customFormat(String pattern, double value) {
+        DecimalFormat myFormatter = new DecimalFormat(pattern);
+        String output = myFormatter.format(value);
+        System.out.println(value + "  " + pattern + "  " + output);
+    }
+}
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/python/CodeAssistance.xml b/ide-features-trainer/res/data/modules/python/CodeAssistance.xml
new file mode 100644 (file)
index 0000000..cd5c55b
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module name="Code Assistance" lessonsPath="CodeAssistance/" version="0.3" id="python.code_assistance" fileType="PROJECT" description="Code format, parameter info and quick popups">
+  <lesson-kt sample="CodeFormat.py.sample" implementationClass="training.learn.lesson.general.assistance.CodeFormatLesson" lang="Python"/>
+  <lesson-kt sample="ParameterInfo.py.sample" implementationClass="training.learn.lesson.general.assistance.ParameterInfoLesson" lang="Python"/>
+  <lesson-kt sample="QuickPopups.py.sample" implementationClass="training.learn.lesson.general.assistance.QuickPopupsLesson" lang="Python"/>
+  <lesson-kt sample="EditorCodingAssistance.py.sample" implementationClass="training.learn.lesson.python.assistance.PythonEditorCodingAssistanceLesson" lang="Python"/>
+</module>
+
diff --git a/ide-features-trainer/res/data/modules/python/CodeAssistance/CodeFormat.py.sample b/ide-features-trainer/res/data/modules/python/CodeAssistance/CodeFormat.py.sample
new file mode 100644 (file)
index 0000000..b18010c
--- /dev/null
@@ -0,0 +1,11 @@
+import sys
+import math
+
+class CodeFormatDemo:
+    a_const = 10000
+    b_const = 500
+    <select>def calc_and_print(self):
+        print(self.a_const * self.b_const)</select>
+    def calc_many_times(self):
+        for i in range(100):
+            self.calc_and_print()
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/python/CodeAssistance/EditorCodingAssistance.py.sample b/ide-features-trainer/res/data/modules/python/CodeAssistance/EditorCodingAssistance.py.sample
new file mode 100644 (file)
index 0000000..5c982d7
--- /dev/null
@@ -0,0 +1,10 @@
+<caret>print("This is program for calculating elementary mathematical functions.")
+print("Enter function argument: ")
+value = float(input())
+sin_x = math.sin(value)
+cos_x = math.cos(value)
+e_pow_x = math.exp(value)
+
+print("sin({:f}) = {:6f}".format(value, sin_x))
+print("cos({:f}) = {:6f}".format(value, cos_x))
+print("e^({:f}) = {:6f}".format(value, e_pow_x))
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/python/CodeAssistance/ParameterInfo.py.sample b/ide-features-trainer/res/data/modules/python/CodeAssistance/ParameterInfo.py.sample
new file mode 100644 (file)
index 0000000..b9c7f4e
--- /dev/null
@@ -0,0 +1,15 @@
+
+class Frame:
+    width = 0
+    height = 0
+    
+    def __init__(self):
+        pass
+    
+    def set_size(self, width, height):
+        self.width = width
+        self.height = height
+        
+
+frame = Frame()
+frame.set_size(<caret>)
diff --git a/ide-features-trainer/res/data/modules/python/CodeAssistance/QuickPopups.py.sample b/ide-features-trainer/res/data/modules/python/CodeAssistance/QuickPopups.py.sample
new file mode 100644 (file)
index 0000000..af8b895
--- /dev/null
@@ -0,0 +1,12 @@
+
+def print_three_times(value):
+    """
+    Prints given value three times
+    """
+    for i in range(0, 3):
+        print(str(value))
+        
+        
+<caret>print_three_times(123)
+print_three_times(1)
+print_three_times('Hello!')
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/ruby/CodeAssistance.xml b/ide-features-trainer/res/data/modules/ruby/CodeAssistance.xml
new file mode 100644 (file)
index 0000000..0707730
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module name="Code Assistance" lessonsPath="CodeAssistance/" version="0.3" id="ruby.code_assistance" fileType="PROJECT" description="Code format, parameter info and quick popups">
+  <lesson-kt sample="CodeFormat.rb.sample" implementationClass="training.learn.lesson.general.assistance.CodeFormatLesson" lang="ruby"/>
+  <lesson-kt sample="ParameterInfo.rb.sample" implementationClass="training.learn.lesson.general.assistance.ParameterInfoLesson" lang="ruby"/>
+  <lesson-kt sample="QuickPopups.rb.sample" implementationClass="training.learn.lesson.general.assistance.QuickPopupsLesson" lang="ruby"/>
+  <lesson-kt sample="EditorCodingAssistance.rb.sample" implementationClass="training.learn.lesson.ruby.assistance.RubyEditorCodingAssistanceLesson" lang="ruby"/>
+</module>
+
diff --git a/ide-features-trainer/res/data/modules/ruby/CodeAssistance/CodeFormat.rb.sample b/ide-features-trainer/res/data/modules/ruby/CodeAssistance/CodeFormat.rb.sample
new file mode 100644 (file)
index 0000000..0efa908
--- /dev/null
@@ -0,0 +1,7 @@
+class CodeFormatDemo
+  attr_reader :a_const, :b_const
+  <select>def calc_and_print
+    print a_const * b_const end</select>
+  def calc_many_times
+    (1..100).each { |i|
+      calc_and_print } end end
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/ruby/CodeAssistance/EditorCodingAssistance.rb.sample b/ide-features-trainer/res/data/modules/ruby/CodeAssistance/EditorCodingAssistance.rb.sample
new file mode 100644 (file)
index 0000000..0defb7e
--- /dev/null
@@ -0,0 +1,16 @@
+<caret>
+class Cat
+  @happiness = 50
+
+  def say_meow
+    print "meow"
+  end
+
+  def eat
+    @happiness = 100
+  end
+end
+
+cat = Cat.new
+cat.say_meow("meow")
+cat.eat
\ No newline at end of file
diff --git a/ide-features-trainer/res/data/modules/ruby/CodeAssistance/ParameterInfo.rb.sample b/ide-features-trainer/res/data/modules/ruby/CodeAssistance/ParameterInfo.rb.sample
new file mode 100644 (file)
index 0000000..c7a2957
--- /dev/null
@@ -0,0 +1,13 @@
+
+class Frame
+  @width = 0
+  @height = 0
+
+  def set_size(width, height)
+    @width = width
+    @height = height
+  end
+end
+
+frame = Frame.new
+frame.set_size(<caret>)
diff --git a/ide-features-trainer/res/data/modules/ruby/CodeAssistance/QuickPopups.rb.sample b/ide-features-trainer/res/data/modules/ruby/CodeAssistance/QuickPopups.rb.sample
new file mode 100644 (file)
index 0000000..cc56762
--- /dev/null
@@ -0,0 +1,11 @@
+
+# Print given value three times
+def print_three_times(value)
+  (1..3).each { |i|
+    print value
+  }
+end
+
+<caret>print_three_times(123)
+print_three_times(1)
+print_three_times("Hello!")
\ No newline at end of file
index fbf72167657592c575f87b9ab7b9faf4f9a3f805..abb8670dad5d255d8cc3931d34ef0474577ca1f5 100644 (file)
@@ -91,6 +91,30 @@ refactoring.menu.start.refactoring=Press {0} to start the {1} refactoring. \
   <strong>Note</strong> that you can learn refactoring shortcuts from the Refactoring menu.
 refactoring.menu.finish.refactoring=To complete refactoring, you need to choose some name or leave it as default and press {0}.
 
+## Code Assistance module
+
+code.format.lesson.name=Code Format
+code.format.reformat.selection=IDE can help you correct code formatting with just one action. \
+ to reformat the selected code fragment with {0}.
+code.format.reformat.file=To reformat the whole file when no lines are selected, use {0}.
+code.format.show.reformat.file.dialog=Use {0} to show reformat settings.
+code.format.optimize.imports=Here you can configure reformat options. For example, switch {0} on and click {1}.
+
+parameter.info.lesson.name=Parameter Info
+parameter.info.use.action=Press {0} to see the method signature.
+parameter.info.add.parameters=Use a width of <strong>175</strong> and a height of <strong>100</strong>.
+
+quick.popups.lesson.name=Quick Popups
+quick.popups.show.documentation=Press {0} to see documentation for the symbol at the caret.
+quick.popups.press.escape=Press {0} to close the popup.
+quick.popups.show.implementation=Press {0} to see the definition of the symbol at the caret.
+
+editor.coding.assistance.lesson.name=Editor Coding Assistance
+editor.coding.assistance.goto.next.error=Press {0} to go to the next highlighted error in the file.
+editor.coding.assistance.show.error.description=Also, you can show error description of the item at the caret using {0}.
+editor.coding.assistance.show.intention=Lets fix this error! Press {0} and select {1}.
+editor.coding.assistance.highlight.usages=Another useful tool is usages highlighting. Press {0} to highlight all usages of the symbol at the caret within the file.
+
 ## Navigation module
 
 declaration.and.usages.lesson.name=Declaration and usages
@@ -431,7 +455,7 @@ js.debugger.part.1.set.breakpoint=So, we can use breakpoints to pause the execut
 js.debugger.part.1.tool.window=Meet the {0} tool window. On its left side, you can find icons for stopping/rerunning configurations, and managing breakpoints. At its top, you can see a few tabs and a bunch of icons for stepping through the code. \nThe {1} tab we''re on is where most of the work is done. On the right, you can see all the {2} grouped by scopes, along with their values. The {3} view shows the call stack. If you go through it, you\u2019ll see the app state at every point of the execution path. Now switch to the {4} tab.
 js.debugger.part.1.scripts.tab=The {0} tab shows the messages logged by an app, including errors. When debugging Node.js apps, WebStorm also shows the {1} tab, where you can run JavaScript code snippets and view the console messages. Switch to the {2} tab to continue.
 js.debugger.part.1.next=The {0} tab lists all the files loaded into the currently running process. You can see the content of any file by double-clicking on it. To move to the second part of this lesson, click the button below or use {1}.
-        
+
 js.debugger.part.2.title=Debugging Code. Part II
 js.debugger.part.2.step.into=<strong>Important</strong>: Please make sure that there\u2019s a breakpoint on line 1 and that the debugger is launched ({0}) and opened on the {1} tab before moving forward.\nLet''s continue with locating a bug in our code and learn a few more things that come in handy when debugging in {2}.To better understand how our code is executed, we could put a few more breakpoints in it and then move from one to another using {3} button ({4}), but there\u2019s a faster way. Let\u2019s step to the next executed line by pressing {5} and using {6} ({7}).
 js.debugger.part.2.buttons=Depending on the situation, you may also like {0} ({1}), which moves the execution in the current file, line by line, without stepping into any function calls. {2} ({3}) lets you select the chained or nested call to step into. Finally, {4} ({5}) finishes the execution of the current function and stops at the next statement after the call. \nNow, what if we want to check the value of an expression? {6} lets you do it quickly with the {7} popup. Press {8} to call it.
diff --git a/ide-features-trainer/src/training/check/CheckParameterInfo.kt b/ide-features-trainer/src/training/check/CheckParameterInfo.kt
deleted file mode 100644 (file)
index 82b931b..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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 training.check
-
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiLiteralExpression
-import com.intellij.psi.PsiMethodCallExpression
-import com.intellij.psi.util.PsiTreeUtil
-
-class CheckParameterInfo : Check {
-  private lateinit var project: Project
-  private lateinit var editor: Editor
-
-  override fun set(project: Project, editor: Editor) {
-    this.project = project
-    this.editor = editor
-  }
-
-  override fun before() {}
-
-  override fun check(): Boolean {
-    val document = editor.document
-    val psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document)
-    val childrenOfType: Collection<PsiMethodCallExpression> = PsiTreeUtil.findChildrenOfType(psiFile, PsiMethodCallExpression::class.java)
-    var myMethodCall: PsiMethodCallExpression? = null
-    for (methodCall in childrenOfType) {
-      myMethodCall = methodCall
-      break
-    }
-    if (myMethodCall == null) return false
-    val literals: Collection<PsiLiteralExpression> = PsiTreeUtil.findChildrenOfType(myMethodCall, PsiLiteralExpression::class.java)
-    if (literals.size != 2) {
-      return false
-    }
-    else {
-      if (literals.toTypedArray()[0].value is Int && literals.toTypedArray()[1].value is Int) {
-        val width = literals.toTypedArray()[0].value as Int?
-        val height = literals.toTypedArray()[1].value as Int?
-        if (width != null && height != null && width == 175 && height == 100) return true
-      }
-    }
-    return false
-  }
-}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/check/CheckQuickPopupsQuickDoc.kt b/ide-features-trainer/src/training/check/CheckQuickPopupsQuickDoc.kt
deleted file mode 100644 (file)
index 44d5076..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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 training.check
-
-import com.intellij.codeInsight.documentation.QuickDocUtil
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-
-class CheckQuickPopupsQuickDoc : Check {
-  private lateinit var project: Project
-  private lateinit var editor: Editor
-
-  override fun set(project: Project, editor: Editor) {
-    this.project = project
-    this.editor = editor
-  }
-
-  override fun before() {}
-
-  override fun check(): Boolean {
-    val activeDocComponent = QuickDocUtil.getActiveDocComponent(project)
-    return activeDocComponent == null || !activeDocComponent.isShowing
-  }
-}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/check/CheckReaderClose.kt b/ide-features-trainer/src/training/check/CheckReaderClose.kt
deleted file mode 100644 (file)
index e65ab71..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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 training.check
-
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import com.intellij.psi.PsiCodeBlock
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiKeyword
-import com.intellij.psi.util.PsiTreeUtil
-
-class CheckReaderClose : Check {
-  private lateinit var project: Project
-  private lateinit var editor: Editor
-
-  override fun set(project: Project, editor: Editor) {
-    this.project = project
-    this.editor = editor
-  }
-
-  override fun before() {}
-
-  override fun check(): Boolean {
-    val document = editor.document
-    val psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document)
-    var finallyKeyword: PsiKeyword? = null
-    val childrenOfType: Collection<PsiKeyword> = PsiTreeUtil.findChildrenOfType(psiFile as PsiElement?, PsiKeyword::class.java)
-    for (psiKeyword in childrenOfType) {
-      if (psiKeyword.text == "finally") finallyKeyword = psiKeyword
-    }
-    if (finallyKeyword == null) return false
-    val nextSibling: PsiElement = finallyKeyword.nextSibling.nextSibling
-    return nextSibling is PsiCodeBlock && nextSibling.getText().contains("fileReader.close();")
-  }
-}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/check/CheckTryFinally.kt b/ide-features-trainer/src/training/check/CheckTryFinally.kt
deleted file mode 100644 (file)
index 460db8a..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 training.check
-
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiKeyword
-import com.intellij.psi.util.PsiTreeUtil
-
-class CheckTryFinally : Check {
-  private lateinit var project: Project
-  private lateinit var editor: Editor
-
-  override fun set(project: Project, editor: Editor) {
-    this.project = project
-    this.editor = editor
-  }
-
-  override fun before() {}
-
-  override fun check(): Boolean {
-    val document = editor.document
-    val psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document)
-    var tryText = false
-    var finallyText = false
-    val childrenOfType: Collection<PsiKeyword> = PsiTreeUtil.findChildrenOfType(psiFile as PsiElement?, PsiKeyword::class.java)
-    for (aChildrenOfType in childrenOfType) {
-      if (aChildrenOfType.text == "try") tryText = true
-      if (aChildrenOfType.text == "finally") finallyText = true
-    }
-    return tryText && finallyText
-  }
-}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/learn/lesson/general/assistance/CodeFormatLesson.kt b/ide-features-trainer/src/training/learn/lesson/general/assistance/CodeFormatLesson.kt
new file mode 100644 (file)
index 0000000..435936c
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright 2000-2020 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 training.learn.lesson.general.assistance
+
+import com.intellij.codeInsight.CodeInsightBundle
+import com.intellij.ide.util.PropertiesComponent
+import com.intellij.openapi.editor.impl.EditorComponentImpl
+import com.intellij.testGuiFramework.framework.GuiTestUtil
+import com.intellij.testGuiFramework.impl.button
+import com.intellij.testGuiFramework.util.Key
+import training.learn.LessonsBundle
+import training.learn.interfaces.Module
+import training.learn.lesson.kimpl.KLesson
+import training.learn.lesson.kimpl.LessonContext
+import training.learn.lesson.kimpl.LessonSample
+
+class CodeFormatLesson(module: Module, override val lang: String, private val sample: LessonSample) :
+  KLesson("Code Format", LessonsBundle.message("code.format.lesson.name"), module, lang) {
+
+  override val lessonContent: LessonContext.() -> Unit = {
+    prepareSample(sample)
+
+    val properties = PropertiesComponent.getInstance()
+    prepareRuntimeTask {
+      properties.setValue("LayoutCode.optimizeImports", false)
+    }
+
+    actionTask("ReformatCode") {
+      LessonsBundle.message("code.format.reformat.selection", action(it))
+    }
+
+    task("ReformatCode") {
+      text(LessonsBundle.message("code.format.reformat.file", action(it)))
+      trigger(it) { editor.selectionModel.selectedText == null }
+      test {
+        GuiTestUtil.shortcut(Key.DOWN)
+        actions(it)
+      }
+    }
+
+    if (lang != "ruby") {
+      task("ShowReformatFileDialog") {
+        text(LessonsBundle.message("code.format.show.reformat.file.dialog", action(it)))
+        triggerStart(it)
+        test {
+          actions(it)
+        }
+      }
+
+      task {
+        val runButtonText = CodeInsightBundle.message("reformat.code.accept.button.text")
+        val optimizeImportsActionText = CodeInsightBundle.message("process.optimize.imports")
+        text(LessonsBundle.message("code.format.optimize.imports", strong(optimizeImportsActionText), strong(runButtonText)))
+        stateCheck {
+          focusOwner is EditorComponentImpl && properties.getBoolean("LayoutCode.optimizeImports")
+        }
+        test {
+          properties.setValue("LayoutCode.optimizeImports", true)
+          ideFrame {
+            button("Run").click()
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/learn/lesson/general/assistance/EditorCodingAssistanceLesson.kt b/ide-features-trainer/src/training/learn/lesson/general/assistance/EditorCodingAssistanceLesson.kt
new file mode 100644 (file)
index 0000000..6daef2c
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright 2000-2020 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 training.learn.lesson.general.assistance
+
+import com.intellij.testGuiFramework.impl.jList
+import training.commands.kotlin.TaskRuntimeContext
+import training.learn.LessonsBundle
+import training.learn.interfaces.Module
+import training.learn.lesson.kimpl.KLesson
+import training.learn.lesson.kimpl.LessonContext
+import training.learn.lesson.kimpl.LessonSample
+
+abstract class EditorCodingAssistanceLesson(module: Module, lang: String, private val sample: LessonSample) :
+  KLesson("Editor Coding Assistance", LessonsBundle.message("editor.coding.assistance.lesson.name"), module, lang) {
+
+  protected abstract fun TaskRuntimeContext.checkErrorFixed(): Boolean
+
+  protected abstract val intentionDisplayName: String
+
+  protected abstract val variableNameToHighlight: String
+
+  override val lessonContent: LessonContext.() -> Unit = {
+    prepareSample(sample)
+
+    actionTask("GotoNextError") {
+      LessonsBundle.message("editor.coding.assistance.goto.next.error", action(it))
+    }
+
+    task("ShowErrorDescription") {
+      text(LessonsBundle.message("editor.coding.assistance.show.error.description", action(it)))
+      trigger(it)
+      test {
+        Thread.sleep(500)
+        actions(it)
+      }
+    }
+
+    task("ShowIntentionActions") {
+      text(LessonsBundle.message("editor.coding.assistance.show.intention", action(it), strong(intentionDisplayName)))
+      stateCheck { checkErrorFixed() }
+      test {
+        actions(it)
+        ideFrame {
+          Thread.sleep(500)
+          jList(intentionDisplayName).clickItem(intentionDisplayName)
+        }
+      }
+    }
+
+    prepareRuntimeTask {
+      val offset = editor.document.charsSequence.indexOf(variableNameToHighlight)
+      if (offset != -1) {
+        editor.caretModel.moveToOffset(offset)
+      }
+    }
+
+    task("HighlightUsagesInFile") {
+      text(LessonsBundle.message("editor.coding.assistance.highlight.usages", action(it)))
+      trigger(it) { checkSymbolAtCaretIsLetter() }
+      test { actions(it) }
+    }
+  }
+
+  private fun TaskRuntimeContext.checkSymbolAtCaretIsLetter(): Boolean {
+    val caretOffset = editor.caretModel.offset
+    val sequence = editor.document.charsSequence
+    return caretOffset != sequence.length && sequence[caretOffset].isLetter()
+  }
+}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/learn/lesson/general/assistance/ParameterInfoLesson.kt b/ide-features-trainer/src/training/learn/lesson/general/assistance/ParameterInfoLesson.kt
new file mode 100644 (file)
index 0000000..a6a5caf
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2000-2020 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 training.learn.lesson.general.assistance
+
+import training.commands.kotlin.TaskRuntimeContext
+import training.learn.LessonsBundle
+import training.learn.interfaces.Module
+import training.learn.lesson.kimpl.KLesson
+import training.learn.lesson.kimpl.LessonContext
+import training.learn.lesson.kimpl.LessonSample
+import kotlin.math.min
+
+class ParameterInfoLesson(module: Module, lang: String, private val sample: LessonSample) :
+  KLesson("Parameter Info", LessonsBundle.message("parameter.info.lesson.name"), module, lang) {
+
+  override val lessonContent: LessonContext.() -> Unit = {
+    prepareSample(sample)
+
+    var caretOffset = 0
+    prepareRuntimeTask {
+      caretOffset = editor.caretModel.offset
+    }
+
+    actionTask("ParameterInfo") {
+      LessonsBundle.message("parameter.info.use.action", action(it))
+    }
+
+    task {
+      text(LessonsBundle.message("parameter.info.add.parameters"))
+      stateCheck { checkParametersAdded(caretOffset) }
+      test {
+        type("175, 100")
+      }
+    }
+  }
+
+  private val parametersRegex = Regex("""175[ \n]*,[ \n]*100[\s\S]*""")
+
+  private fun TaskRuntimeContext.checkParametersAdded(caretOffset: Int): Boolean {
+    val sequence = editor.document.charsSequence
+    val partOfSequence = sequence.subSequence(caretOffset, min(caretOffset + 20, sequence.length))
+    return partOfSequence.matches(parametersRegex)
+  }
+}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/learn/lesson/general/assistance/QuickPopupsLesson.kt b/ide-features-trainer/src/training/learn/lesson/general/assistance/QuickPopupsLesson.kt
new file mode 100644 (file)
index 0000000..88aadda
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2000-2020 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 training.learn.lesson.general.assistance
+
+import com.intellij.codeInsight.documentation.DocumentationComponent
+import com.intellij.codeInsight.documentation.QuickDocUtil
+import com.intellij.codeInsight.hint.ImplementationViewComponent
+import com.intellij.testGuiFramework.framework.GuiTestUtil
+import com.intellij.testGuiFramework.util.Key
+import training.commands.kotlin.TaskRuntimeContext
+import training.learn.LessonsBundle
+import training.learn.interfaces.Module
+import training.learn.lesson.kimpl.KLesson
+import training.learn.lesson.kimpl.LessonContext
+import training.learn.lesson.kimpl.LessonSample
+
+class QuickPopupsLesson(module: Module, lang: String, private val sample: LessonSample) :
+  KLesson("Quick Popups", LessonsBundle.message("quick.popups.lesson.name"), module, lang) {
+
+  override val lessonContent: LessonContext.() -> Unit = {
+    prepareSample(sample)
+
+    task("QuickJavaDoc") {
+      text(LessonsBundle.message("quick.popups.show.documentation", action(it)))
+      triggerByUiComponentAndHighlight(highlightBorder = false, highlightInside = false) { _: DocumentationComponent -> true }
+      test { actions(it) }
+    }
+
+    task {
+      text(LessonsBundle.message("quick.popups.press.escape", action("EditorEscape")))
+      stateCheck { checkDocComponentClosed() }
+      test {
+        GuiTestUtil.shortcut(Key.ESCAPE)
+      }
+    }
+
+    task("QuickImplementations") {
+      text(LessonsBundle.message("quick.popups.show.implementation", action(it)))
+      triggerByUiComponentAndHighlight(highlightBorder = false, highlightInside = false) { _: ImplementationViewComponent -> true }
+      test { actions(it) }
+    }
+  }
+
+  fun TaskRuntimeContext.checkDocComponentClosed(): Boolean {
+    val activeDocComponent = QuickDocUtil.getActiveDocComponent(project)
+    return activeDocComponent == null || !activeDocComponent.isShowing
+  }
+}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/learn/lesson/java/assistance/JavaEditorCodingAssistanceLesson.kt b/ide-features-trainer/src/training/learn/lesson/java/assistance/JavaEditorCodingAssistanceLesson.kt
new file mode 100644 (file)
index 0000000..949d58d
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2000-2020 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 training.learn.lesson.java.assistance
+
+import com.intellij.codeInsight.daemon.QuickFixBundle
+import training.commands.kotlin.TaskRuntimeContext
+import training.learn.interfaces.Module
+import training.learn.lesson.general.assistance.EditorCodingAssistanceLesson
+import training.learn.lesson.kimpl.LessonSample
+
+class JavaEditorCodingAssistanceLesson(module: Module, lang: String, sample: LessonSample) :
+  EditorCodingAssistanceLesson(module, lang, sample) {
+
+  override fun TaskRuntimeContext.checkErrorFixed(): Boolean {
+    return editor.document.charsSequence.contains("throws IOException")
+  }
+
+  override val intentionDisplayName: String
+    get() = QuickFixBundle.message("add.exception.to.throws.family")
+
+  override val variableNameToHighlight: String = "lines"
+}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/learn/lesson/python/assistance/PythonEditorCodingAssistanceLesson.kt b/ide-features-trainer/src/training/learn/lesson/python/assistance/PythonEditorCodingAssistanceLesson.kt
new file mode 100644 (file)
index 0000000..63a490a
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2000-2020 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 training.learn.lesson.python.assistance
+
+import com.intellij.openapi.application.ApplicationBundle
+import training.commands.kotlin.TaskRuntimeContext
+import training.learn.interfaces.Module
+import training.learn.lesson.general.assistance.EditorCodingAssistanceLesson
+import training.learn.lesson.kimpl.LessonSample
+
+class PythonEditorCodingAssistanceLesson(module: Module, lang: String, sample: LessonSample) :
+  EditorCodingAssistanceLesson(module, lang, sample) {
+
+  override fun TaskRuntimeContext.checkErrorFixed(): Boolean {
+    return editor.document.charsSequence.contains("import math")
+  }
+
+  override val intentionDisplayName: String
+    get() = ApplicationBundle.message("settings.editor.scheme.import", "'math'")
+
+  override val variableNameToHighlight: String = "value"
+}
\ No newline at end of file
diff --git a/ide-features-trainer/src/training/learn/lesson/ruby/assistance/RubyEditorCodingAssistanceLesson.kt b/ide-features-trainer/src/training/learn/lesson/ruby/assistance/RubyEditorCodingAssistanceLesson.kt
new file mode 100644 (file)
index 0000000..ce468d7
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2000-2020 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 training.learn.lesson.ruby.assistance
+
+import org.jetbrains.plugins.ruby.RBundle
+import training.commands.kotlin.TaskRuntimeContext
+import training.learn.interfaces.Module
+import training.learn.lesson.general.assistance.EditorCodingAssistanceLesson
+import training.learn.lesson.kimpl.LessonSample
+
+class RubyEditorCodingAssistanceLesson(module: Module, lang: String, sample: LessonSample) :
+  EditorCodingAssistanceLesson(module, lang, sample) {
+
+  override fun TaskRuntimeContext.checkErrorFixed(): Boolean {
+    return editor.document.charsSequence.contains("cat.say_meow()")
+  }
+
+  override val intentionDisplayName: String
+    get() = RBundle.message("inspection.argcount.extra.argument.fix")
+
+  override val variableNameToHighlight: String = "@happiness"
+}
\ No newline at end of file