Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 3 commits
  • 14 files changed
  • 0 commit comments
  • 1 contributor
View
13 TODO.md
@@ -1,9 +1,18 @@
+[.] faire fonctionner le debug:
+ [.] fusionner ctrl alt s et alt l h,
+ [.] qu'on arrive a automatiquement a connecter eclipse au debogueur
+ [.] verifier que le debug dans les sources prend les bons sources,
+ [.] qu'on peut toujours plonger dans le code via F3,
+ [.] que ça fonctionne en mode debug ou en mode run
+ [.] que la doc fonctionne,
+ [.] qu'un projet comme cljs-start fonctionne (compilation, etc.)
+ [.] fusionner run/debug from editor avec ctrl alt s (plutôt qu'un comportement identique à run/debug from ifile)
## Product
- [X] PR for Leiningen for abort/exit + issues on the github repositories that have issues with changing the "Suppressed exit" message ( https://github.com/search?p=1&q=%22Suppressed+exit%22&ref=searchresults&type=Code )
- [X] Finish the commit with adding *exit-...* and changing for ex-info/ex-data
-- [.] Fix the issue with the product not running anymore !!!
+- [X] Fix the issue with the product not running anymore !!!
+- [ ] Address Mark Engelbert concern on having the same behavior for lein / non lein startups ( changing the namespace, closing the REPL implying terminating the process, etc. )
- [.] Handle projects with :lein-pedantic :abort when refreshing dependencies => Show the error properly (see https://github.com/cursiveclojure/cursive/issues/122#issuecomment-29259144 for how Cursive Clojure does this)
-- [ ] Address Mark Engelbert concern on having the same behavior for lein / non lein startupts ( changing the namespace, closing the REPL implying terminating the process, etc. )
### TODO
View
16 ccw.core/plugin.xml
@@ -35,6 +35,22 @@
</or>
</enablement>
</consolePatternMatchListener>
+ <consolePatternMatchListener
+ id="ccw.editors.clojure.debugProcessHyperlink"
+ regex="Listening for transport dt_socket at address: \d+">
+ <class class="ccw.util.GenericExecutableExtension">
+ <parameter
+ name="factory"
+ value="ccw.editors.clojure.debug-hyperlink/factory">
+ </parameter>
+ </class>
+ <enablement>
+ <or>
+ <test property="org.eclipse.ui.console.consoleTypeTest" value="javaStackTraceConsole"/>
+ <test property="org.eclipse.debug.ui.processTypeTest" value="java"/>
+ </or>
+ </enablement>
+ </consolePatternMatchListener>
</extension>
View
12 ccw.core/src/clj/ccw/eclipse.clj
@@ -16,6 +16,7 @@
FileLocator
IAdaptable]
[org.eclipse.jdt.core IJavaProject]
+ [org.eclipse.debug.core ILaunchConfiguration ILaunch]
[org.eclipse.ui.handlers HandlerUtil]
[org.eclipse.ui IEditorPart
PlatformUI
@@ -26,7 +27,8 @@
[org.eclipse.ui.actions WorkspaceModifyDelegatingOperation]
[java.io File IOException]
[ccw CCWPlugin]
- [ccw.util PlatformUtil DisplayUtil]))
+ [ccw.util PlatformUtil DisplayUtil]
+ [ccw.launching LaunchUtils]))
(defn adapter
"Invokes Eclipse Platform machinery to try by all means to adapt object to
@@ -115,7 +117,13 @@
(project [this] (project (resource this)))
ExecutionEvent
- (project [this] (project (resource this))))
+ (project [this] (project (resource this)))
+
+ ILaunchConfiguration
+ (project [^ILaunchConfiguration l] (LaunchUtils/getProject l))
+
+ ILaunch
+ (project [^ILaunch l] (LaunchUtils/getProject l)))
(extend-protocol IResourceCoercion
nil
View
59 ccw.core/src/clj/ccw/editors/clojure/debug_hyperlink.clj
@@ -0,0 +1,59 @@
+(ns ccw.editors.clojure.debug-hyperlink
+ "Detect and create hyperlinks in Consoles when a pattern describing a JVM
+ listening to some debug port is found.
+ The first time the pattern is encountered for the currently attached console,
+ will automatically start a remote process for connecting to this port"
+ (:require [ccw.string :as s]
+ [ccw.launch :as launch]
+ [ccw.eclipse :as e])
+ (:use [clojure.test])
+ (:import [org.eclipse.ui.console PatternMatchEvent TextConsole]))
+
+(def ^:private debug-port-pattern #"\d+")
+
+(defn remote-connect
+ "Launch a remote java debugging connection on port for project."
+ [project port]
+ (launch/launch :debug
+ {:type-id :remote-java
+ :private true
+ :name (str (and project (e/project-name project)) " VM")
+ :launch-in-background false
+ :java/project-name (and project (e/project-name project))
+ :java/vm-connector (launch/vm-connector :socket-attach-vm-connector)
+ :java/connect-map {"port" port
+ "hostname" "localhost"}}))
+
+(defn match-found
+ "state contains the console instance, and a set of seen (if many) debug port patterns.
+ This allows to e.g. only process opening remote connections once, even if
+ match-found is called several times on the same text."
+ [^PatternMatchEvent event ^TextConsole {:keys [console debug-ports] :as state}]
+ (let [offset (.getOffset event)
+ length (.getLength event)
+ document (.getDocument console)
+ s (.get document offset length)
+ [debug-port] (re-seq debug-port-pattern s)
+ remote-connect #(remote-connect
+ (some-> console .getProcess .getLaunch e/project)
+ debug-port)
+ hyperlink (reify org.eclipse.ui.console.IHyperlink
+ (linkActivated [this] (remote-connect))
+ (linkExited [this])
+ (linkEntered [this]))]
+ (.addHyperlink console hyperlink offset length)
+ (when-not (debug-ports debug-port)
+ (e/ui (remote-connect)))
+ (update-in state [:debug-ports] conj debug-port)))
+
+(defn make []
+ (let [state (atom nil)]
+ (reify org.eclipse.ui.console.IPatternMatchListenerDelegate
+ (connect [this console] (reset! state {:console console
+ :debug-ports #{}}))
+ (disconnect [this] (reset! state nil))
+ (matchFound [this event]
+ (swap! state (partial match-found event))
+ nil))))
+
+(defn factory "plugin.xml hook" [ _ ] (make))
View
6 ccw.core/src/clj/ccw/editors/clojure/nrepl_hyperlink.clj
@@ -17,14 +17,14 @@
document (.getDocument console)
s (.get document offset length)
[[url]] (re-seq pattern s)
- open-repl-view #(ccw.repl.REPLView/connect url true)
+ open-repl-view #(ccw.repl.REPLView/connect url console (some-> console .getProcess .getLaunch) true)
hyperlink (reify org.eclipse.ui.console.IHyperlink
(linkActivated [this] (open-repl-view))
(linkExited [this])
(linkEntered [this]))]
(.addHyperlink console hyperlink offset length)
- (when-not (nrepl-urls url)
- (e/ui (open-repl-view)))
+ #_(when-not (nrepl-urls url)
+ (e/ui (open-repl-view)))
(update-in state [:nrepl-urls] conj url)))
(defn make []
View
13 ccw.core/src/clj/ccw/launch.clj
@@ -64,7 +64,14 @@
{:ccw
"ccw.launching.clojure"
:java
- IJavaLaunchConfigurationConstants/ID_JAVA_APPLICATION})
+ IJavaLaunchConfigurationConstants/ID_JAVA_APPLICATION
+ :remote-java
+ IJavaLaunchConfigurationConstants/ID_REMOTE_JAVA_APPLICATION})
+
+(def vm-connector
+ "Identifiers for socket attaching and socket listening connectors"
+ {:socket-attach-vm-connector IJavaLaunchConfigurationConstants/ID_SOCKET_ATTACH_VM_CONNECTOR
+ :socket-listen-vm-connector IJavaLaunchConfigurationConstants/ID_SOCKET_LISTEN_VM_CONNECTOR})
(def attrs-map
"Launch configuration pre-existing attributes."
@@ -83,6 +90,10 @@
:java/classpath IJavaLaunchConfigurationConstants/ATTR_CLASSPATH
:java/default-classpath IJavaLaunchConfigurationConstants/ATTR_DEFAULT_CLASSPATH
:java/project-name IJavaLaunchConfigurationConstants/ATTR_PROJECT_NAME
+
+ ;; specific for remote java
+ :java/vm-connector IJavaLaunchConfigurationConstants/ATTR_VM_CONNECTOR
+ :java/connect-map IJavaLaunchConfigurationConstants/ATTR_CONNECT_MAP
})
#_(defn default-jre "Default JRE installed in workbench" [] (JavaRuntime/getDefaultVMInstall))
View
4 ccw.core/src/clj/ccw/leiningen/classpath_container.clj
@@ -261,8 +261,8 @@
[exc java-project]
(if-not exc
[(e/resource java-project) "unknown problem (missing exception)"]
- (let [exc (if (check-class java.lang.reflect.InvocationTargetException exc) (.getCause exc) exc)
- exc (if (check-class clojure.lang.ExceptionInfo exc) (.getCause exc) exc)]
+ (let [exc (if (check-class java.lang.reflect.InvocationTargetException exc) (or (.getCause exc) exc) exc)
+ exc (if (check-class clojure.lang.ExceptionInfo exc) (or (.getCause exc) exc) exc)]
(cond
(check-class DependencyResolutionException exc)
(dependency-resolution-message exc java-project)
View
8 ccw.core/src/clj/ccw/leiningen/launch.clj
@@ -23,13 +23,9 @@
:name launch/default-jre-container-name}]
:java/default-classpath false
:java/vm-arguments (str " -Dfile.encoding=UTF-8"
- " -Dmaven.wagon.http.ssl.easy=false"
- ;; TODO see if we can safely remove this argument
- ;; " -Dleiningen.original.pwd=\"/Users/laurentpetit/tmp\""
- )
+ " -Dmaven.wagon.http.ssl.easy=false")
:java/main-type-name "clojure.main"
- :java/program-arguments (str "-m ccw.leiningen.main " command)
- }))
+ :java/program-arguments (str "-m ccw.leiningen.main " command)}))
(defn lein
"project can be nil"
View
9 ccw.core/src/java/ccw/ClojureCore.java
@@ -507,6 +507,15 @@ public static String findMaybeLibNamespace(IFile file) {
}
return null;
}
+
+ /**
+ * @return starting with a leading slash "/", the root classpath relative
+ * path of this file
+ */
+ public static String getAsRootClasspathRelativePath(IFile file) {
+ return "/lop/core.clj";
+ }
+
/**
* @see <code>findMaybeLibNamespace(IFile file)</code>
*/
View
2 ccw.core/src/java/ccw/editors/clojure/ClojureEditor.java
@@ -283,7 +283,7 @@ protected void createActions() {
action = new Action() {
@Override
public void run() {
- new ClojureLaunchShortcut().launch(ClojureEditor.this, ILaunchManager.RUN_MODE);
+ new ClojureLaunchShortcut().launch(ClojureEditor.this, ILaunchManager.DEBUG_MODE);
};
};
action.setActionDefinitionId(IClojureEditorActionDefinitionIds.LAUNCH_REPL);
View
3 ccw.core/src/java/ccw/editors/clojure/LoadFileAction.java
@@ -62,6 +62,7 @@ public void run() {
final REPLView repl = REPLView.activeREPL.get();
if (repl != null && !repl.isDisposed()) {
evaluateFileText(repl, editor.getDocument().get(), filePath, sourcePath, fileName);
+ // FIXME: normal that we switch in namespace if start (if no repl), and not if not start ... ?
} else if (editorFile != null) {
CCWPlugin.getTracer().trace(TraceOptions.LAUNCHER, "No active REPL found (",
(repl == null) ? "active repl is null" : "active repl is disposed",
@@ -69,7 +70,7 @@ public void run() {
new Thread(new Runnable() {
public void run() {
final IProject project = editorFile.getProject();
- new ClojureLaunchShortcut().launchProject(project, ILaunchManager.RUN_MODE);
+ new ClojureLaunchShortcut().launchProject(project, ILaunchManager.DEBUG_MODE);
DisplayUtil.asyncExec(new Runnable() {
public void run() {
REPLView repl = CCWPlugin.getDefault().getProjectREPL(project);
View
37 ccw.core/src/java/ccw/launching/ClojureLaunchDelegate.java
@@ -19,6 +19,7 @@
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
@@ -107,7 +108,7 @@ protected IStatus run(final IProgressMonitor monitor) {
monitor.beginTask("Waiting for new REPL process to be ready...", IProgressMonitor.UNKNOWN);
- final Number port = (Number)Connection.find("clojure.tools.nrepl.ack", "wait-for-ack").invoke(60000);
+ final Number port = (Number)Connection.find("clojure.tools.nrepl.ack", "wait-for-ack").invoke(300000);
cancelOrAck.countDown();
if (monitor.isCanceled()) {
@@ -238,12 +239,21 @@ public String getVMArguments(ILaunchConfiguration configuration) throws CoreExce
@Override
public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException {
+ String superProgramArguments = super.getProgramArguments(configuration);
if (isLeiningenConfiguration(configuration)) {
- // Leiningen configuration does not need (yet) program arguments tweaks
- return super.getProgramArguments(configuration);
+ List<IFile> filesToLaunch = LaunchUtils.getFilesToLaunchList(configuration);
+ if (filesToLaunch.size() > 0) {
+ int headlessReplOffset = superProgramArguments.indexOf("repl :headless");
+ String arguments = superProgramArguments.substring(0, headlessReplOffset) +
+ " " + createFileLoadInjections(filesToLaunch) +
+ " -- " + superProgramArguments.substring(headlessReplOffset);
+ return arguments;
+ } else {
+ return superProgramArguments;
+ }
}
- String userProgramArguments = super.getProgramArguments(configuration);
+ String userProgramArguments = superProgramArguments;
if (isLaunchREPL(configuration)) {
String filesToLaunchArguments = LaunchUtils.getFilesToLaunchAsCommandLineList(configuration, false);
@@ -273,13 +283,28 @@ public String getProgramArguments(ILaunchConfiguration configuration) throws Cor
}
}
+ private String createFileLoadInjections(List<IFile> filesToLaunch) {
+
+ assert filesToLaunch.size() > 0;
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(" update-in :injections conj \"");
+ for (IFile file: filesToLaunch) {
+ //String path = file.getLocation().toOSString();
+ String path = ClojureCore.getAsRootClasspathRelativePath(file);
+ int offset = path.lastIndexOf(".clj");
+ sb.append("(load \\\"" + path.substring(0, offset) + "\\\")");
+ }
+ sb.append("\" ");
+ return sb.toString();
+ }
+
private static boolean isLaunchREPL(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(LaunchUtils.ATTR_CLOJURE_START_REPL, true);
}
public static boolean isLeiningenConfiguration(ILaunchConfiguration configuration) throws CoreException {
- return false;
- //return configuration.getAttribute(LaunchUtils.ATTR_LEININGEN_CONFIGURATION, false);
+ return configuration.getAttribute(LaunchUtils.ATTR_LEININGEN_CONFIGURATION, false);
}
public static boolean isAutoReloadEnabled (ILaunch launch) {
View
40 ccw.core/src/java/ccw/launching/ClojureLaunchShortcut.java
@@ -152,17 +152,17 @@ public void run() {
}
private boolean useLeiningenLaunchConfiguration(IProject project) throws CoreException {
- return false;
- //return project.hasNature(CCWPlugin.LEININGEN_NATURE_ID);
+ return project.hasNature(CCWPlugin.LEININGEN_NATURE_ID);
}
protected void launchProject(IProject project, IFile[] filesToLaunch, String mode) {
try {
- ILaunchConfiguration config = findLaunchConfiguration(project);
- if (config == null) {
- if (useLeiningenLaunchConfiguration(project)) {
- config = createLeiningenLaunchConfiguration(project);
- } else {
+ ILaunchConfiguration config;
+ if (useLeiningenLaunchConfiguration(project)) {
+ config = createLeiningenLaunchConfiguration(project, (mode!= null && mode.equals(ILaunchManager.DEBUG_MODE)));
+ } else {
+ config = findLaunchConfiguration(project);
+ if (config == null) {
System.out.println("creating basic configuration (no lein configuration)");
config = createConfiguration(project, null);
}
@@ -172,11 +172,7 @@ protected void launchProject(IProject project, IFile[] filesToLaunch, String mod
ILaunchConfigurationWorkingCopy runnableConfiguration =
config.copy(config.getName() + " #" + incTempLaunchCount(project.getName()));
try {
- if (useLeiningenLaunchConfiguration(project)) {
- // Nothing special
- } else {
- LaunchUtils.setFilesToLaunchString(runnableConfiguration, Arrays.asList(filesToLaunch));
- }
+ LaunchUtils.setFilesToLaunchString(runnableConfiguration, Arrays.asList(filesToLaunch));
if (filesToLaunch.length > 0) {
runnableConfiguration.setAttribute(LaunchUtils.ATTR_NS_TO_START_IN, ClojureCore.findMaybeLibNamespace(filesToLaunch[0]));
}
@@ -191,22 +187,26 @@ protected void launchProject(IProject project, IFile[] filesToLaunch, String mod
}
}
- private ILaunchConfiguration createLeiningenLaunchConfiguration(IProject project) {
- clojure.lang.IPersistentMap configMap =
+ private ILaunchConfiguration createLeiningenLaunchConfiguration(IProject project, boolean createInDebugMode) {
+ String command = " update-in :dependencies conj \"[ccw/ccw.server \\\"0.1.0\\\"]\" -- update-in :injections conj \"(require 'ccw.debug.serverrepl)\" -- repl :headless ";
+ if (createInDebugMode) {
+ command = " update-in :jvm-opts concat \"[\\\"-Xdebug\\\" \\\"-Xrunjdwp:transport=dt_socket,server=y,suspend=n\\\"]\" -- "
+ + command;
+ }
+
+ clojure.lang.IPersistentMap configMap =
(clojure.lang.IPersistentMap)
leiningenConfiguration._("lein-launch-configuration",
project,
- "update-in :dependencies conj \"[ccw/ccw.server \\\"0.1.0\\\"]\" -- update-in :injections conj \"(require 'ccw.debug.serverrepl)\" -- repl :headless");
+ command);
configMap = configMap.assoc(Keyword.intern("type-id"), Keyword.intern("ccw"));
- configMap = configMap.assoc(Keyword.intern("name"), project.getName() + " Leiningen");
+ configMap = configMap.assoc(Keyword.intern("name"), project.getName() + " Leiningen VM");
configMap = configMap.assoc(LaunchUtils.ATTR_CLOJURE_START_REPL, true);
configMap = configMap.assoc(LaunchUtils.ATTR_LEININGEN_CONFIGURATION, true);
- configMap = configMap.assoc(Keyword.intern("private"), false);
- configMap = configMap.assoc(Keyword.intern("launch-in-background"), false);
+ configMap = configMap.assoc(Keyword.intern("private"), true);
return (ILaunchConfiguration)
- launch._("launch-configuration",
- configMap);
+ launch._("launch-configuration", configMap);
}
private ILaunchConfiguration findLaunchConfiguration(IProject project) throws CoreException {
View
5 ccw.product/ccw.product
@@ -34,7 +34,7 @@ Apache Software Foundation http://www.apache.org/
startupMessageRect="7,490,500,25"
startupForegroundColor="1C0F3C" />
<launcher name="Counterclockwise">
- <linux icon="images/ccw-48x48.xpm"/>
+ <linux icon="images/ccw-48x48.xpm"/> <!-- why 48x48, shouldn't it be 256x256 as for vogella's -->
<macosx icon="images/ccw.icns"/>
<solaris/>
<win useIco="true">
@@ -265,6 +265,9 @@ litigation.
<feature id="org.eclipse.wst.web_ui.feature"/>
<feature id="com.github.eclipsecolortheme.feature"/>
<feature id="org.eclipse.pde"/>
+ <!-- Try this eclipseuitheme option
+ <feature id="com.github.eclipseuitheme.themes.feature"/>
+ -->
</features>
<configurations>

No commit comments for this range

Something went wrong with that request. Please try again.