Documetation + Improve a bit the log preference page

Change-Id: Ic4fe9ded5b3e5faa4bb8f4e92853e8bdd885a917
Signed-off-by: Mickael Istria <mistria@redhat.com>
diff --git a/doc/img/language-server-idea.png b/doc/img/language-server-idea.png
deleted file mode 100644
index 31f8ceb..0000000
--- a/doc/img/language-server-idea.png
+++ /dev/null
Binary files differ
diff --git a/doc/index.adoc b/doc/index.adoc
deleted file mode 100644
index 8907450..0000000
--- a/doc/index.adoc
+++ /dev/null
@@ -1,37 +0,0 @@
-= Eclipse Language Services =
-
-Start point for documentation related to https://github.com/eclipselabs/eclipse-language-service[eclipse language services]
-
-The idea is to have a proof of concept of Language Services on Eclipse by: 
-
-* implementing a subclass of SSE Structured Editor that sends data to a language service
-
-As protocol we refer to the https://github.com/Microsoft/vscode-languageserver-protocol[vscode languageserver protocol], implemented under MIT license by the team of https://github.com/egamma[E.Gamma,  (MicroSoft)] .
-
-
-== Server Side ==
-
-Protocol: https://github.com/Microsoft/vscode-languageserver-protocol 
-
-The easiest way to have a language server running is to install VSCode: http://code.visualstudio.com/
-
-. How to run the JavaScript language server
-. Start VSCode
-. Clone a git repo with JS code: https://github.com/josdejong/mathjs
-. Open the cloned folder in VSCode
-
-== Eclipse IDE Side ==
-
-We choose to start implementing a JavaScript Editor as VSCode already provides a Language Server Service for a JavaScript editor. 
-You can extend this by adding any other editor, as example XML, Java, Xtext, PHP, HTML, XSLT, SASS, etc.  
-
-* We created a plugin `org.eclipse.lsp4e`, which implements an extension to `org.eclipse.wst.jsdt.ui.javaCompletionProposalComputer`. 
-* The LanguageCompletionProposalComputer#computeCompletionProposals(..) is the method that actually provides content assist.
-* To run, you need to setup for JSDT, explained here: https://www.youtube.com/watch?v=gOz1hk-ohMA
-
-== Important Notes and References == 
-
-* Sven put an interesting comment to ensime-server
-see: https://github.com/ensime/ensime-server/issues/1498
-* Initial prototype of language server protocol extension for Che using the TypeFox API:
-https://github.com/eclipse/che/pull/1323/commits/e250864c89228875723649268a72a87d91057033  
\ No newline at end of file
diff --git a/doc/language-server.adoc b/doc/language-server.adoc
deleted file mode 100644
index 79148bf..0000000
--- a/doc/language-server.adoc
+++ /dev/null
@@ -1,67 +0,0 @@
-Eclipse and Language Server based Editors
-=========================================
-
-Patrik Suzzi <psuzzi@gmail.com>
-v 0.1, June 2016
-
-== Language Server Protocol (LSP) == 
-
-The idea is to have Editors as clients, communicating with a Language Server using a defined protocol, where:
-
-* The _client sends_ partial information (edit deltas) to the Language Server; 
-* The _server parses and computes_ the AST,  
-* The _server responds_ to the editor with code completion proposals, compilation errors, etc.
-
-image:img/language-server-idea.png[]
-
-=== Concrete Implementations ===
-
-This approach separates editing from language processing. It is born to support web editors (thin clients), and now there are also desktop editors (thick clients) based on it. As an example: _Visual Studio Code_, _Eclipse Che_, _Xtext_, _Typefox_, and other products and enterprises are implementing/using this approach.
-
-=== Current Market ===
-
-* *_VSCode_* is the reference implementation, and it is known to be an excellent product for web-based languages editing. Protocol and server are open-source, _MIT-licensed_, and written in JavaScript. It provides multi-platform, desktop clients for Win, Linux, and Mac.
-* *_Eclipse Che_* is a web-based editor, part of the Eclipse ecosystem, For what I understand it is using the same approach; so there should be an implementation of Language Server - although it is not clear to me whether it implements the same protocol -
-* *_Xtext_* is providing Language Server support to Eclipse Che, and the Typefox team has already implemented a Java interface to define the protocol. However, it is understood that implementing a Java Thick Client is out of their scope. 
-
-=== Need for a Proof of Concept in Eclipse ===
-
-The competition also landed on multi-platform editors; the opportunity to increase the value of the community and the possible growth of a market for Language Servers, are some of the reasons that pushed us, at the Eclipse unconference, to analyze the approach and problem, and decided to start with a PoC.
-
-= PoC: Eclipse Editor using Lang server  =
-
-A simple proof of concept: build an Eclipse Editor that communicate to a LanguageServer using the  https://github.com/Microsoft/vscode-languageserver-protocol[vscode-languageserver-protocol].
-
-The easiest way to test, is to extend the JSDT editor, and use a protocol implementation, to reuse the existing vscode language server. Below are some interesting references:
-
-* Extend the JSDT JavaScript editor. As example, we can read this article:  http://codeandme.blogspot.fr/2014/05/extending-jsdt-adding-your-own-content.html[Extending JSDT editor]
-* Re-use a Java implementation of the protocol, that is VS Code independent can be found here: https://github.com/TypeFox/ls-api[TypeFox/ls-api] 
- 
-
-Sven Efftinge (sven@efftinge.de) sven@efftinge.de via eclipse.org 
-10 Jun 2016, 10:08 PM 
-
-to Discussions 
-A Java implementation of the protocol, that is VS Code independent can be found here: https://github.com/TypeFox/ls-api
-It defines all the structures in Java interfaces and beans and takes care of the (de)serialization to/from json.
-It is currently used by Che, Xtext, and the a JavaC based java language server.
-
-== Typefox/ls-api ==
-
-The Typefox guys are currently working on an implementation of the protocol to connect Eclipse Che to Xtext language server. They are not interested in Eclipse Client development, and there are some limitations in the typefox ls-api: 
-
-* The repo uses xtend api, and you need to use gradle to build it. 
-* Seems the ls-api is using system.out/in, instead of named pipes or sockets to connect 
-
-=== Details on ls-api ===
-
-
-
-The interface `Language Server`,(in `io.typefox.lsapi.services`) is for the impl of https://github.com/Microsoft/vscode-languageserver-protocol
-
-The class `JsonBasedLanguageServer` is a sample impl of a server
-
-=== Client ===
-
-Client is an editor that implements the basic methods. See `TextDocumentService`. 
-
diff --git a/documentation/integrating-a-language-server.md b/documentation/integrating-a-language-server.md
new file mode 100644
index 0000000..379a3d7
--- /dev/null
+++ b/documentation/integrating-a-language-server.md
@@ -0,0 +1,13 @@
+## Properly integrating a language server with LSP4E
+
+### General principle
+
+Use the `org.eclipse.lsp4e.languageServer` extension in `plugin.xml` to define a language server (ie how to start it and connect to it) and to associate it with one or many content-types.
+
+### Examples
+
+See [multiple examples in the test](../org.eclipse.lsp4e.test/plugin.xml).
+
+### Tips and Tricks
+
+* Use the `ProcessStreamConnectionProvider` if your LS is accessible as a process.
\ No newline at end of file
diff --git a/documentation/troubleshooting-language-servers.md b/documentation/troubleshooting-language-servers.md
new file mode 100644
index 0000000..2c26540
--- /dev/null
+++ b/documentation/troubleshooting-language-servers.md
@@ -0,0 +1,17 @@
+## Troubleshooting language servers with LSP4E
+
+### Log and analyze LSP messages
+
+In the vast majority of cases, when troubleshooting a Language Server integration, the unique source of truth are the LSP messages that are exchanged between the IDE (Eclipse IDE with LSP4E here) and the language server.
+
+LSP4E allows to easily get those messages, in both directions, logged in a file. To get it, go to _Preferences > Language Servers > Logs_ and find the interesting Language Server to inspect. Then double click on the `Log to file` column to enable logging. A popup will suggest that you restart the IDE, but what you can simply close all files associated to the target Language Server and reopen them, what matters isn't that the IDE restarts, but more that the Language Server restarts.
+
+Then in the _<workspace>/languageServers-log_ folder, you'll see files containing the raw messages and a timestamp. You can then inspect for typical cause of failures such as:
+* an expected message was not sent or received
+* a message contains an erroneous value
+* a message doesn't receive a response in due time
+* ...
+
+### Debug the language server
+
+TODO
\ No newline at end of file
diff --git a/documentation/using-language-server-via-configuration-no-code.md b/documentation/using-language-server-via-configuration-no-code.md
new file mode 100644
index 0000000..061ecc8
--- /dev/null
+++ b/documentation/using-language-server-via-configuration-no-code.md
@@ -0,0 +1,46 @@
+## Using a language server with Eclipse IDE, without code
+
+Eclipse LSP4E provides a way to dynamically define a language server and associate it with some files in the Eclipse IDE, without coding the integration.
+
+This is quite handy for testing a lanaguage server, however, it's not recommended to rely on it for actual production usage (you should prefer using the `org.eclipse.lsp4e.languageServers` extension point for that).
+
+Requirements for the language server
+* The Language Server must be "runnable" from command-line
+* The Language Server must start a specific process
+* The Language Server must support communication via __stdin & stdout__ (other streams not supported for this case)
+
+### Step 1: Identify or define the content-type for your Language Server targets
+
+In Preferences > Content-Type, check that either a content-type is already defined for your target files, and that this content type maps such files (by name or extension). If no content-type does that, you can augment an existing content-type or create a new content-type to associate with your target file name patterns/extensions.
+
+📝 The content-type must be a descendant of the _Text_ content-type.
+
+### Step 2: Create a Launch Configuration describing how to start your Language Server
+
+In the usual _Launch Configurations_ dialog, define how your langauge server should be started. Depending on your language server, you may want to start it as a Java Program or as an External Program... Use the various fields to customize things like command-line arguments or environment variables if necessary.
+
+To help you with development and testing, it's usually nice to be able to monitor the language server output. So you may want to tick the _Command > Allocate Console_ checkbox.
+
+### Step 3: Associate content-type with Language Server launch configuration
+
+_Preferences > Language Servers_, on the bottom block _Add..._. Then select
+* on the left: your target content-type
+* on the right: the Launch Configuration that can start your language server
+
+Another option on the association dialog allows to select the "launch mode". For configurations that allows it, you can for example use _debug_ instead of _run_ and that will allow you to benefit from debug capabilities.
+
+Then apply.
+
+### Step 4: See the result in action and monitor the Language Server
+
+Open one of your target files with the Generic Editor (_Right-click > Open With > Generic Editor_), if the file is already open in some editor, you'll need to close and reopen it. Once open in the Generic Editor, you should enjoy rich edition: diagnostics/problems, hover, completion, outline... coming from the Language Server.
+
+If you've enabled the _Allocate Console_ option, the console should show the messages sent by the Language Server to LSP4E.
+
+In the _Debug_ view, you can monitor the state of your Language Server process. Depending on the Launch Configuration type and other options, you have more or less monitoring and control capabilities available.
+
+### Bonus: Developing, testing and debugging a Language Server in the same Eclipse IDE
+
+During [Step 3](#Step 3: Associate content-type with Language Server launch configuration), if you used the _debug_ mode, then the _Debug_ view should show you more details about your language server running. Typically, if your language server is developed with Java or Node and you used related launch configurations, you'll see in debug the various frames/stacks/threads... that you can pause and inspect. Breakpoints would work too.
+
+So LSP4E is also a good way to develop and debug your language-server in the same IDE instance with this approach: you can have the sources of your language server imported, create a Launch Configuration for your Language Server from the project, place breakpoints and so on, associate this launch configuration with the target content-type and start editing the target files to see the breakpoints hit in your IDE.
\ No newline at end of file
diff --git a/org.eclipse.lsp4e/META-INF/MANIFEST.MF b/org.eclipse.lsp4e/META-INF/MANIFEST.MF
index ea6c5ab..049ad8d 100644
--- a/org.eclipse.lsp4e/META-INF/MANIFEST.MF
+++ b/org.eclipse.lsp4e/META-INF/MANIFEST.MF
@@ -39,7 +39,8 @@
  org.eclipse.ltk.ui.refactoring,
  org.eclipse.ui.browser,
  org.eclipse.ui.intro;bundle-version="3.5.200",
- com.google.guava;bundle-version="27.0.0"
+ com.google.guava;bundle-version="27.0.0",
+ org.eclipse.e4.core.commands
 Bundle-ClassPath: .
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LoggingStreamConnectionProviderProxy.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LoggingStreamConnectionProviderProxy.java
index f432dfb..017e08c 100644
--- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LoggingStreamConnectionProviderProxy.java
+++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LoggingStreamConnectionProviderProxy.java
@@ -34,7 +34,18 @@
 import org.eclipse.ui.console.MessageConsoleStream;
 
 public class LoggingStreamConnectionProviderProxy implements StreamConnectionProvider {
-	public static final String LOG_DIRECTORY = "languageServers-log"; //$NON-NLS-1$
+
+	public static File getLogDirectory() {
+		IPath root = ResourcesPlugin.getWorkspace().getRoot().getLocation();
+		if (root == null) {
+			return null;
+		}
+		File logFolder = new File(root.addTrailingSeparator().toPortableString(), "languageServers-log"); //$NON-NLS-1$
+		if (!(logFolder.exists() || logFolder.mkdirs()) || !logFolder.isDirectory() || !logFolder.canWrite()) {
+			return null;
+		}
+		return logFolder;
+	}
 
 	private static final String FILE_KEY = "file.logging.enabled"; //$NON-NLS-1$
 	private static final String STDERR_KEY = "stderr.logging.enabled"; //$NON-NLS-1$
@@ -268,12 +279,8 @@
 		if (logFile != null) {
 			return logFile;
 		}
-		IPath root = ResourcesPlugin.getWorkspace().getRoot().getLocation();
-		if (root == null) {
-			return null;
-		}
-		File logFolder = new File(root.addTrailingSeparator().toPortableString() + LOG_DIRECTORY);
-		if (!(logFolder.exists() || logFolder.mkdirs()) || !logFolder.isDirectory() || !logFolder.canWrite()) {
+		File logFolder = getLogDirectory();
+		if (logFolder == null) {
 			return null;
 		}
 		File file = new File(logFolder, id + ".log"); //$NON-NLS-1$
diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/LoggingPreferencePage.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/LoggingPreferencePage.java
index db288c8..bd60256 100644
--- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/LoggingPreferencePage.java
+++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/LoggingPreferencePage.java
@@ -31,6 +31,7 @@
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.TableViewerColumn;
 import org.eclipse.jface.viewers.ViewerCell;
+import org.eclipse.jface.wizard.WizardDialog;
 import org.eclipse.lsp4e.ContentTypeToLSPLaunchConfigEntry;
 import org.eclipse.lsp4e.ContentTypeToLanguageServerDefinition;
 import org.eclipse.lsp4e.LanguageServerPlugin;
@@ -46,9 +47,11 @@
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.wizards.datatransfer.SmartImportWizard;
 
 public class LoggingPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
 
@@ -176,9 +179,17 @@
 		Label infoLabel = new Label(loggingComposite, SWT.NONE);
 		infoLabel.setText(Messages.preferencesPage_logging_info);
 		infoLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
+		Link logFolderLabel = new Link(loggingComposite, SWT.NONE);
+		logFolderLabel.setText(NLS.bind(Messages.preferencesPage_logging_fileLogsLocation, LoggingStreamConnectionProviderProxy.getLogDirectory()));
+		logFolderLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
+		logFolderLabel.addSelectionListener(widgetSelectedAdapter(e -> {
+			SmartImportWizard importWizard = new SmartImportWizard();
+			importWizard.setInitialImportSource(LoggingStreamConnectionProviderProxy.getLogDirectory());
+			WizardDialog dialog = new WizardDialog(logFolderLabel.getShell(), importWizard);
+			dialog.open();
+		}));
 		Label fileLoggingLabel = new Label(loggingComposite, SWT.NONE);
-		fileLoggingLabel.setText(NLS.bind(Messages.PreferencesPage_logging_toFile_description,
-				LoggingStreamConnectionProviderProxy.LOG_DIRECTORY));
+		fileLoggingLabel.setText(Messages.PreferencesPage_logging_toFile_description);
 		Button disableFileLogging = new Button(loggingComposite, SWT.NONE);
 		disableFileLogging.setText(Messages.PreferencePage_enablementCondition_disableAll);
 		disableFileLogging.addSelectionListener(widgetSelectedAdapter(e -> {
diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/Messages.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/Messages.java
index 77d3c2a..83abf56 100644
--- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/Messages.java
+++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/Messages.java
@@ -38,6 +38,7 @@
 	public static String PreferencesPage_logging_toConsole_title;
 	public static String PreferencesPage_logging_toConsole_description;
 	public static String preferencesPage_logging_info;
+	public static String preferencesPage_logging_fileLogsLocation;
 	public static String PreferencesPage_restartWarning_title;
 	public static String PreferencesPage_restartWarning_message;
 	public static String PreferencesPage_restartWarning_restart;
diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/messages.properties b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/messages.properties
index efa202d..01af835 100644
--- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/messages.properties
+++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/ui/messages.properties
@@ -30,10 +30,11 @@
 PreferencePage_enablementCondition_enableAll=Enable all
 PreferencePage_enablementCondition_disableAll=Disable all
 PreferencesPage_logging_toFile_title=Log to File
-PreferencesPage_logging_toFile_description=Log language server communications to folder ({0})
+PreferencesPage_logging_toFile_description=Log language server communications to file
 PreferencesPage_logging_toConsole_title=Log to Console
 PreferencesPage_logging_toConsole_description=Log language server communications to console
 preferencesPage_logging_info=Double click on individual server logging statuses to set logging on a per server basis
+preferencesPage_logging_fileLogsLocation=File logs are stored in \uD83D\uDCC2<A>{0}</A>
 PreferencesPage_restartWarning_title=Restart Required
 PreferencesPage_restartWarning_message=Changes to the logging settings may require a restart to fully take affect. Would you like to restart Eclipse SDK to apply the changes?
 PreferencesPage_restartWarning_restart=Restart Now