diff --git a/testing/code_view/code_view_tests.srctrlprj b/testing/code_view/code_view_tests.srctrlprj new file mode 100644 index 00000000..21c27481 --- /dev/null +++ b/testing/code_view/code_view_tests.srctrlprj @@ -0,0 +1,42 @@ + + + +Test Suites:\n\n +[::\tmCODE_AREA_TESTS\ts\tp]\n +[::\tmLOCAL_REFERENCE_TESTS\ts\tp]\n +[::\tmSNIPPET_LIST_TESTS\ts\tp]\n +[::\tmSINGLE_FILE_TESTS\ts\tp]\n +[::\tmFILE_BAR_TESTS\ts\tp]\n +[::\tmERROR_TESTS\ts\tp]\n + + + + c++17 + + + unknown + x86_64 + unknown + unknown + + 0 + + + data/file_bar_files/non_indexed.h + data/file_bar_files/non_indexed_and_incomplete.h + + C++ Source Group + + .cpp + .cxx + .cc + + + data + + enabled + C++ Source Group + + + 7 + diff --git a/testing/code_view/data/code_area_tests.cpp b/testing/code_view/data/code_area_tests.cpp new file mode 100644 index 00000000..7f0fc750 --- /dev/null +++ b/testing/code_view/data/code_area_tests.cpp @@ -0,0 +1,277 @@ +#include +#include +#include + +namespace CODE_AREA_TESTS +{ + +// TEST: hover +// START ---------------------------------------------------------------------- + +namespace hover // <- ACTION 1: hover namespace +{ + void function(size_t number, bool flag) // <- ACTION 2: function + { + if (flag) + { + number += 10; // <- ACTION 3: hover number + } + } +} + +// RESULTS 1: +// - namespace name gets border +// - namespace and it's scope show highlight at line numbers +// - tooltip shows CODE_AREA_TESTS::hover + +// RESULTS 2: +// - function name gets border +// - function and it's scope show highlight at line numbers +// - tooltip shows function signature + +// RESULTS 3: +// - variable name and all references get highlighted +// - every line with a reference shows a highlight at the line number +// - no tooltip is shown + +// END ------------------------------------------------------------------------ + + + +// TEST: Activating symbol +// START ---------------------------------------------------------------------- + +void some_function() // <- ACTION: click on function +{ +} + +// RESULTS: +// - function is activated +// - reference navigation at top shows "1 reference" + +// END ------------------------------------------------------------------------ + + + +// TEST: Activating reference +// START ---------------------------------------------------------------------- + +void func() {} + +void reference_test() +{ + func(); // <- ACTION: click on function call +} + +// RESULTS: +// - function is activated +// - definition location and refernence location is active +// - reference navigation at top shows "2 references" + +// END ------------------------------------------------------------------------ + + + +// TEST: Activating qualifier +// START ---------------------------------------------------------------------- + +namespace qualifier +{ + void func() {} +} + +void qualifier_test() +{ + /* ACTION: Click on qualifier -> */ qualifier::func(); +} + +// RESULTS: +// - qualifier is activated +// - clicked qualifier location is not highlighted +// - reference navigation shows "1 reference" + +// END ------------------------------------------------------------------------ + + + +// TEST: members have implicit reference locations at type definition +// START ---------------------------------------------------------------------- +class TestType +{}; + +class Sample // <- ACTION 1: click class name +{ +public: + TestType m_type; +}; + +Sample s; + +// RESULT 1: shows list: +// Sample +// Sample::m_type + +// ACTION 2: click on Sample::m_type + +// RESULT 2: member has 2 references, one at class name + +// END ------------------------------------------------------------------------ + + + +// TEST: clicking on overriden method activates it immediately +// START ---------------------------------------------------------------------- +class Base +{ + virtual void foo(); +}; + +class Override + : public Base +{ + void foo() override; // <- ACTION: click on foo() +}; + +// RESULT: Override::foo() is activated + +// END ------------------------------------------------------------------------ + + +// TEST: clicking on macro usage shows list of symbols referenced at location +// START ---------------------------------------------------------------------- + +#define POW(__number__, __power__) \ + std::pow(__number__, __power__) + +int a = POW(42, 2); // <- ACTION 1: click on POW + +// RESULT 1: shows list: +// POW +// pow +// std + +// ACTION 2: click on POW in the list + +// RESULT 2: POW is activated + +// END ------------------------------------------------------------------------ + + + +// TEST: function tooltip +// START ---------------------------------------------------------------------- + +std::vector very_long_function_name_with_three_parameters( // <- ACTION 1: hover function + const std::vector& strings, size_t number, bool flag) +{ + return strings; +} + +// RESULT 1: +// - Tooltip shows signature as defined in code with qualifier: +// std::vector +// CODE_AREA_TESTS::very_long_function_name_with_three_parameters( +// const std::vector& strings, +// size_t number, +// bool flag +// ) + +// ACTION 2: hover all symbols in the tooltip + +// RESULT 2: all types, qualifier and function is clickable + +// ACTION 3: click on one of them + +// RESULT 3: Clicked symbol is activated + +// END ------------------------------------------------------------------------ + + + +// TEST: auto tooltip +// START ---------------------------------------------------------------------- + +void auto_function(const std::vector& strings) +{ + auto it = strings.begin(); // <- ACTION 1: hover auto +} + +// RESULT 1: Tooltip shows underlying type + +// END ------------------------------------------------------------------------ + + + +// TEST: typedef tooltip +// START ---------------------------------------------------------------------- + +typedef unsigned int uint; + +uint b = 12; // <- ACTION 1: hover uint + +// RESULT 1: Tooltip shows underlying type + +// END ------------------------------------------------------------------------ + + + +// TEST: horizontal panning +// START ---------------------------------------------------------------------- + +void very_long_function_name_with_three_parameters_that_is_so_long_it_doesnt_fit_on_the_screen(const std::vector& strings, size_t number, bool flag); + +// ACTION 1: Hold SHIFT and drag code left and right + +// RESULT 1: It pans left and right + +// ACTION 2: Switch to snippet/single mode and repeat + +// RESULT 2: same thing + +// END ------------------------------------------------------------------------ + + + +// TEST: copy & paste +// START ---------------------------------------------------------------------- + +void copy_function( + const std::vector& strings, + size_t number, + bool flag) +{ + for (auto str : strings) + { + number++; + } +} + +// ^ ACTION: Select whole piece of code and paste it into a text editor + +// RESULT: All code is pasted. + +// END ------------------------------------------------------------------------ + + + +// TEST: copy file path +// START ---------------------------------------------------------------------- + +// ACTION: Open context menu and choose "Copy Full Path" and paste it to a text editor. + +// RESULT: Full path to the file is pasted + +// END ------------------------------------------------------------------------ + + + +// TEST: open containing folder +// START ---------------------------------------------------------------------- + +// ACTION: Open context menu and choose "Open Containing Folder". + +// RESULT: The filesystem explorer is opened showing the "data" directory of this testsuite. + +// END ------------------------------------------------------------------------ + +} diff --git a/testing/code_view/data/error_tests.cpp b/testing/code_view/data/error_tests.cpp new file mode 100644 index 00000000..d13ff1fa --- /dev/null +++ b/testing/code_view/data/error_tests.cpp @@ -0,0 +1,64 @@ + +namespace ERROR_TESTS +{ + +// TEST: show errors +// START ---------------------------------------------------------------------- + +// ACTION: click 'show errors' in the title bar + +// RESULTS: +// - title bar shows 3 references +// - code shows 3 red locations +// - error table is shown at bottom of view with 3 errors +// - search view shows 'error error_tests.cpp' + +// END ------------------------------------------------------------------------ + + + +// TEST: hover error +// START ---------------------------------------------------------------------- + +int x = y(); // <- ACTION: hover error locations + +// RESULT: tooltip with error message is shown: use of undeclared identifier 'y' + +// END ------------------------------------------------------------------------ + + + +// TEST: error activation +// START ---------------------------------------------------------------------- + +class Sample +{ +public: + bool foo() const + { + something(); // <- ACTION: click on error + } + + voi something() + { + } +}; + +// RESULT: +// - Error is highlighted in the error table +// - Reference navigation on top is updated with 2/3 references + +// END ------------------------------------------------------------------------ + + + +// TEST: error iteration +// START ---------------------------------------------------------------------- + +// ACTION: use reference navigation on top back and forward + +// RESULT: one error after another is activated and scrolled to + +// END ------------------------------------------------------------------------ + +} diff --git a/testing/code_view/data/file_bar_files/incomplete.h b/testing/code_view/data/file_bar_files/incomplete.h new file mode 100644 index 00000000..c72c681f --- /dev/null +++ b/testing/code_view/data/file_bar_files/incomplete.h @@ -0,0 +1,13 @@ + +int a = b(); + +// TEST: incomplete file - continued +// START ---------------------------------------------------------------------- + +// RESULT 1: file button of 'incomplete.h' has file icon with x + +// ACTION 2: Hover file name + +// RESULT 2: Tooltip also shows "incomplete file:" + +// END ------------------------------------------------------------------------ diff --git a/testing/code_view/data/file_bar_files/non_indexed.h b/testing/code_view/data/file_bar_files/non_indexed.h new file mode 100644 index 00000000..0b22068f --- /dev/null +++ b/testing/code_view/data/file_bar_files/non_indexed.h @@ -0,0 +1,13 @@ + +int c = 10; + +// TEST: non-indexed file - continued +// START ---------------------------------------------------------------------- + +// RESULT 1: file button of 'non_indexed.h' has hatching + +// ACTION 2: Hover file name + +// RESULT 2: Tooltip also shows "non-indexed file:" + +// END ------------------------------------------------------------------------ diff --git a/testing/code_view/data/file_bar_files/non_indexed_and_incomplete.h b/testing/code_view/data/file_bar_files/non_indexed_and_incomplete.h new file mode 100644 index 00000000..a46372fc --- /dev/null +++ b/testing/code_view/data/file_bar_files/non_indexed_and_incomplete.h @@ -0,0 +1,13 @@ + +int d = d(); + +// TEST: non-indexed & incomplete file - continued +// START ---------------------------------------------------------------------- + +// RESULT 1: file button of 'non_indexed_and_incomplete.h' has hatching and file icon with x + +// ACTION 2: Hover file name + +// RESULT 2: Tooltip also shows "incomplete non-indexed file:" + +// END ------------------------------------------------------------------------ diff --git a/testing/code_view/data/file_bar_tests.cpp b/testing/code_view/data/file_bar_tests.cpp new file mode 100644 index 00000000..8a7b29f7 --- /dev/null +++ b/testing/code_view/data/file_bar_tests.cpp @@ -0,0 +1,71 @@ + +namespace FILE_BAR_TESTS +{ + +// TEST: file button tooltip +// START ---------------------------------------------------------------------- + +// ACTION: Hover file name in the title bar + +// RESULT: The tooltip shows the whole path + +// END ------------------------------------------------------------------------ + + + +// TEST: file changed indicator +// START ---------------------------------------------------------------------- + +// ACTION 1: Make changes to this file, then switch back here + +// RESULT 1: The file name has an * added at the end. + +// ACTION 2: Hover file name + +// RESULT 2: Tooltip also shows "out-of-data file:" + +// END ------------------------------------------------------------------------ + + + +// TEST: non-indexed file +// START ---------------------------------------------------------------------- + +#include "file_bar_files/non_indexed.h" // <- ACTION 1: activate file + +// END ------------------------------------------------------------------------ + + + +// TEST: incomplete file +// START ---------------------------------------------------------------------- + +#include "file_bar_files/incomplete.h" // <- ACTION: activate file + +// END ------------------------------------------------------------------------ + + + +// TEST: non-indexed & incomplete file +// START ---------------------------------------------------------------------- + +#include "file_bar_files/non_indexed_and_incomplete.h" // <- ACTION: activate file + +// END ------------------------------------------------------------------------ + + + +// TEST: edit project in overview +// START ---------------------------------------------------------------------- + +// ACTION 1: go to overview and hover project name + +// RESULT 1: File button has pen icon and tooltip shows 'edit project' + +// ACTION 2: click project name in code file bar + +// RESULT 2: Edit project dialog is shown + +// END ------------------------------------------------------------------------ + +} diff --git a/testing/code_view/data/local_reference_tests.cpp b/testing/code_view/data/local_reference_tests.cpp new file mode 100644 index 00000000..d5bb2779 --- /dev/null +++ b/testing/code_view/data/local_reference_tests.cpp @@ -0,0 +1,139 @@ + +namespace LOCAL_REFERENCE_TESTS +{ + + +// TEST: local symbol activation +// START ---------------------------------------------------------------------- + +void local_symbols() +{ + for (int i = 0; i < 10; i++) // <- ACTION: click on i + { + i++; + } +} + +// RESULTS 1: +// - All 4 locations of i are highlighted +// - Each line with a reference shows a line highlight +// - The local reference navigation appears at the top showing "4 local references" + +// ACTION 2: + +// RESULTS 2: +// - The local references disappear +// - The local reference navigation disappears + +// END ------------------------------------------------------------------------ + + + +// TEST: scope start and end brackets activation +// START ---------------------------------------------------------------------- + +void scope_start_and_end() +{ + for (int i = 0; i < 10; i++) + { // <- ACTION 1: click on { + i++; + } +} // <- ACTION 2: click on } + +// RESULT 1: The start and end curly brackets of the scope are highlighted same as local symbols +// RESULT 2: Same behavior + +// END ------------------------------------------------------------------------ + + + +// TEST: local reference navigation for local symbols +// START ---------------------------------------------------------------------- + +void local_reference_navigation() +{ + for (int i = 0; i < 10; i++) // <- ACTION 1: click on i + { + /* RESULT 2: view scrolls here when this reference is active -> */ i--; + i++; + } +} + +// ACTION 2: use local reference navigation at top to iterate all 5 references back and forward + +// RESULTS 2: +// - Each reference is separately highlighted and the view scrolled if necessary +// - The local reference navigation shows "X/5 local references" while navigating + +// ACTION 3: Use the menu actions "Edit -> Next Local Reference" and "Edit -> Previous Local Reference" and their shortcuts + +// RESULT 3: Same behavior as with buttons + +// END ------------------------------------------------------------------------ + + + +// TEST: local symbol activation in snippet mode +// START ---------------------------------------------------------------------- + +void some_referenced_function() { } // <- ACTION 1: activate function + +// ACTION 2: switch to snippet mode + +void local_reference_navigation_snippet_mode() +{ + some_referenced_function(); + + for (int i = 0; i < 10; i++) // <- ACTION 3: click on i +/* +// RESULT 3: 3 local references are active + +// ACTION 4: Expand snippet to full scope of function at the snippet bottom +*/ + + + + + + + + + i++; +} + +// RESULT 4: 4 local references are active + +// END ------------------------------------------------------------------------ + + + +// TEST: local reference navigation for edges +// START ---------------------------------------------------------------------- + +void some_called_function() {} // <- ACTION 1: activate function + +void local_reference_edge_navigation() +{ + some_called_function(); + + /* RESULT: view scrolls here -> */ some_called_function(); + + + some_called_function(); +} + +/* +// RESULT 1: 3 local references are active + +// ACTION 2: click on the call edge between the two functions in the graph + +// RESULTS 2: +// - The references are iterated in forward direction +// - Each reference is separately highlighted and the view scrolled if necessary +// - The local reference navigation shows "X/3 local references" while navigating +*/ + +// END ------------------------------------------------------------------------ + +} + diff --git a/testing/code_view/data/single_file_files/header.h b/testing/code_view/data/single_file_files/header.h new file mode 100644 index 00000000..ef3fb49a --- /dev/null +++ b/testing/code_view/data/single_file_files/header.h @@ -0,0 +1,91 @@ + +// TEST: activation loads file - continued +// START ---------------------------------------------------------------------- + +// RESULT: This file is visible + +// END ------------------------------------------------------------------------ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#pragma once + +class Reference +{ +}; + + +// TEST: reference navigation switches to file - continued +// START ---------------------------------------------------------------------- + +// RESULT: This file is visible and scrolled here + +// ACTION: Use reference navigation at top and navigate to next reference. + +// END ------------------------------------------------------------------------ + + + + + + + + + + + + + + + + + + + + + + + + + +// TEST: edge click switches to file - continued +// START ---------------------------------------------------------------------- + +// RESULT: This file is visible and scrolled here + +// ACTION: Click on edge from ref_func2() to Reference2 + +// END ------------------------------------------------------------------------ + +class Reference2 +{ +}; diff --git a/testing/code_view/data/single_file_files/reference.h b/testing/code_view/data/single_file_files/reference.h new file mode 100644 index 00000000..0317b916 --- /dev/null +++ b/testing/code_view/data/single_file_files/reference.h @@ -0,0 +1,71 @@ +#include "header.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// TEST: reference navigation switches to file - continued +// START ---------------------------------------------------------------------- + +// RESULT: This file is visible and scrolled here + +// ACTION: navigate to next reference to go back + +// END ------------------------------------------------------------------------ + +void ref_func() +{ + Reference ref; +} diff --git a/testing/code_view/data/single_file_files/reference2.h b/testing/code_view/data/single_file_files/reference2.h new file mode 100644 index 00000000..40fc091b --- /dev/null +++ b/testing/code_view/data/single_file_files/reference2.h @@ -0,0 +1,14 @@ +#include "header.h" + + +// TEST: edge click switches to file - continued +// START ---------------------------------------------------------------------- + +// RESULT: This file is visible and scrolled here + +// END ------------------------------------------------------------------------ + +void ref_func2() +{ + Reference2 ref; +} diff --git a/testing/code_view/data/single_file_tests.cpp b/testing/code_view/data/single_file_tests.cpp new file mode 100644 index 00000000..fc165323 --- /dev/null +++ b/testing/code_view/data/single_file_tests.cpp @@ -0,0 +1,36 @@ + +namespace SINGLE_FILE_TESTS +{ + +// ACTION: switch to single file mode with button at top right + + +// TEST: activation loads file +// START ---------------------------------------------------------------------- + +#include "single_file_files/header.h" // <- ACTION: activate file + +// END ------------------------------------------------------------------------ + + + +// TEST: reference navigation switches to file +// START ---------------------------------------------------------------------- + +#include "single_file_files/reference.h" + +Reference r; // <- ACTION: activate class + +// END ------------------------------------------------------------------------ + + + +// TEST: edge click switches to file +// START ---------------------------------------------------------------------- + +#include "single_file_files/reference2.h" + +Reference2 r2; // <- ACTION: activate class + +// END ------------------------------------------------------------------------ +} diff --git a/testing/code_view/data/snippet_list_files/header.h b/testing/code_view/data/snippet_list_files/header.h new file mode 100644 index 00000000..1ca5de56 --- /dev/null +++ b/testing/code_view/data/snippet_list_files/header.h @@ -0,0 +1,21 @@ + +// TEST: snippets expanded by default - continued +// START ---------------------------------------------------------------------- + +// RESULTS: +// - There are 4 snippets +// - The first 3 are expanded +// - The first one shows this whole file + +// END ------------------------------------------------------------------------ + + +#ifndef __HEADER__ +#define __HEADER__ + +int sum(int a, int b) +{ + return a + b; +} + +#endif diff --git a/testing/code_view/data/snippet_list_files/zimpl.h b/testing/code_view/data/snippet_list_files/zimpl.h new file mode 100644 index 00000000..a1611f47 --- /dev/null +++ b/testing/code_view/data/snippet_list_files/zimpl.h @@ -0,0 +1,12 @@ + +#include "header.h" + +int multiply(int a, int b) +{ + int r = 0; + for (int i = 1; i < b; i++) + { + r = sum(r, a); + } + return r; +} diff --git a/testing/code_view/data/snippet_list_files/zimpl2.h b/testing/code_view/data/snippet_list_files/zimpl2.h new file mode 100644 index 00000000..69304055 --- /dev/null +++ b/testing/code_view/data/snippet_list_files/zimpl2.h @@ -0,0 +1,14 @@ + +#include "header.h" + +int divide(int a, int b) +{ + int c = 0; + int r = 0; + while (r < a) + { + r = sum(r, b); + c++; + } + return c; +} diff --git a/testing/code_view/data/snippet_list_tests.cpp b/testing/code_view/data/snippet_list_tests.cpp new file mode 100644 index 00000000..5c3b4fc8 --- /dev/null +++ b/testing/code_view/data/snippet_list_tests.cpp @@ -0,0 +1,179 @@ + +namespace SNIPPET_LIST_TESTS +{ + +// ACTION: switch to snippet mode with button at top right + + + +// TEST: snippets expanded by default +// START ---------------------------------------------------------------------- + +#include "snippet_list_files/header.h" // <- ACTION: activate file + +#include "snippet_list_files/zimpl.h" +#include "snippet_list_files/zimpl2.h" + +// END ------------------------------------------------------------------------ + + + +// TEST: scope expansion +// START ---------------------------------------------------------------------- + +class A +{ +public: + int foo() + { + m_member = 10; + + + + + + + + int r = 0; + + for (int a = 0; a < 10; a++) + { + r += a; + } + + return r; + } + +private: + int m_member; // <- ACTION 1: activate member + +/* +// RESULTS 1: +// - 2 snippets are visible within the same file +// - this whole comment block is visible + +// ACTION 2: expand bottom scope of first snippet: foo() +// RESULT 2: snippets are expanded and merged to one + +// ACTION 3: click the class A expansion at the bottom +*/ + + + + + +}; + +/* +// RESULT 3: the whole class area is visible + +// ACTION 4: click the namespace expansion at the top +// RESULT 4: the whole namespace area is visible + +// ACTION 5: click the file name expansion at the bottom +// RESULTS 5: +// - the whole file is visible +// - there are not scope expansion lines anymore +*/ + +// END ------------------------------------------------------------------------ + + + +// TEST: file title bar and scroll bar stay fixed +// START ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + +// ACTION: scroll up and down +// RESULT: The file bar at the top and the scrollbar at the bottom stay in view + +// END ------------------------------------------------------------------------ + + + +// TEST: minimizing snippets +// START ---------------------------------------------------------------------- + +int a = sum(1, 2); // <- ACTION 1: activate sum + +/* +// ACTION 2: click '-' button in snippet bar +// RESULT 2: snippet gets minimized + +// ACTION 3: click '=' button in snippet bar +// RESULT 3: snippet expands again + +// ACTION 4: click into the file bar area +// RESULT 4: snippet gets minimized + +// ACTION 5: click into the file bar area again +// RESULT 5: snippet gets expanded again +*/ + +// END ------------------------------------------------------------------------ + + + +// TEST: maximizing snippets +// START ---------------------------------------------------------------------- + +int b = sum(3, 4); // <- ACTION 1: activate sum + +/* +// ACTION 2: click '[]' button in snippet bar +// RESULT 2: view switches to single file mode + +// ACTION 3: click '=' button in snippet bar +// RESULT 3: view switches back to snippet view +*/ + +// END ------------------------------------------------------------------------ + + + +// TEST: reference navigation and scrolling +// START ---------------------------------------------------------------------- + +int c = sum(5, 6); // <- ACTION 1: activate sum + /* RESULT: view is scrolled here -> */ int d = sum(7, 8); + +/* +// ACTION 2: Use reference navigation at top back and forward +// RESULTS 2: +// - focus is switched to all locations of sum() +// - if snippet was minimized, it gets expanded +// - view is scrolled to active reference vertically and horizontally +*/ + +// END ------------------------------------------------------------------------ + + + +// TEST: edge click and scrolling +// START ---------------------------------------------------------------------- + +int e; // <- ACTION 1: activate int + +/* +// ACTION 2: In the graph activate the edge between divide & int +// RESULTS 2: +// - snippet is expanded +// - view is scrolled down +// - reference navigation is updated +// - local reference navigation is visible +*/ + +// END ------------------------------------------------------------------------ +} + + + + + + + + + + + + +// END OF FILE diff --git a/testing/missing.txt b/testing/missing.txt new file mode 100644 index 00000000..e4ed2943 --- /dev/null +++ b/testing/missing.txt @@ -0,0 +1,49 @@ + +WINDOW + First launch - eula, license + About + Help Menu + dock widgets + title bars + overview - shortcut + window layout - save/reset + start window - recent projects, buttons, update check + screen search - graph, code + tooltips + +PROJECT SETUP + source groups - add, remove, copy, disable, rename + multi language + header search - validation and detection + global header detection + file endings + exclude - file, directory, wildcart + project location within subdirectory - e.g. indexed path = ../../src + +PREFERENCES + font size - shortcut + font face + color scheme + animations + built-in types + logging + update-check + +INDEXING + refresh types - shortcuts + errors - filter and limit + +BOOKMARKS + node + edge + from graph + work after close, restart + work after refresh + shortcuts + +CODE + show definition + +PLUGIN COMMUNICATION + from + to