Skip to content

Commit

Permalink
Merge remote branch 'cemerick/repl-ui' into repl-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentpetit committed Mar 8, 2011
2 parents 032fb50 + b4fb081 commit 5b22def
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 32 deletions.
1 change: 1 addition & 0 deletions ccw.core/src/ccw/builder/ClojureBuilder.java
Expand Up @@ -100,6 +100,7 @@ private boolean onlyClassesOrOutputFolderRelatedDelta() throws CoreException {
for (IFolder outputPath: getSrcFolders(getProject()).values()) {
folders.add(outputPath.getFullPath());
}
folders.add(getProject().getFolder(".settings").getFullPath());

delta_loop: for (IResourceDelta d: getDelta(getProject()).getAffectedChildren()) {
for (IPath folder: folders) {
Expand Down
5 changes: 3 additions & 2 deletions ccw.core/src/ccw/editors/antlrbased/LoadFileAction.java
Expand Up @@ -58,17 +58,18 @@ public void run() {
if (proj != null) {
for (IFolder f : proj.sourceFolders()) {
if (f.getProjectRelativePath().isPrefixOf(editorFile.getProjectRelativePath())) {
sourcePath = f.getLocation().toOSString();
sourcePath = editorFile.getProjectRelativePath().makeRelativeTo(f.getProjectRelativePath()).toOSString();
break;
}
}
}
if (sourcePath == null) sourcePath = filePath;

REPLView repl = REPLView.activeREPL.get();
if (repl != null && !repl.isDisposed()) {
EvaluateTextUtil.evaluateText(repl, ";; Loading file " + editorFile.getProjectRelativePath().toOSString(), true);
try {
EvaluateTextUtil.evaluateText(repl, (String)loadFileCommand.invoke(editor.getDocument().get(), filePath, sourcePath), false);
EvaluateTextUtil.evaluateText(repl, (String)loadFileCommand.invoke(editor.getDocument().get(), sourcePath, editorFile.getName()), false);
Actions.ShowActiveREPL.execute(false);
} catch (Exception e) {
CCWPlugin.logError("Could not load file " + filePath, e);
Expand Down
4 changes: 4 additions & 0 deletions ccw.core/src/ccw/repl/REPLView.java
Expand Up @@ -2,6 +2,7 @@

import java.net.ConnectException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.ILaunch;
Expand Down Expand Up @@ -70,6 +71,7 @@ public class REPLView extends ViewPart implements IAdaptable {
}

private static final Keyword inputExprLogType = Keyword.intern("in-expr");
private static final Pattern boostIndent = Pattern.compile("^", Pattern.MULTILINE);

// TODO would like to eliminate separate log view, but:
// 1. PareditAutoEditStrategy gets all text from a source document, and bails badly if its not well-formed
Expand Down Expand Up @@ -97,6 +99,8 @@ public class REPLView extends ViewPart implements IAdaptable {
public REPLView () {}

private void copyToLog (StyledText s) {
// sadly, need to reset text on the ST in order to get formatting/style ranges...
s.setText(boostIndent.matcher(s.getText()).replaceAll(" ").replaceFirst("^\\s+", "=> "));
int start = logPanel.getCharCount();
try {
log.invoke(logPanel, s.getText(), inputExprLogType);
Expand Down
76 changes: 51 additions & 25 deletions ccw.core/src/ccw/repl/cmdhistory.clj
@@ -1,8 +1,12 @@
(ns ccw.repl.cmdhistory
(:use (clojure.contrib def core))
(:import
ccw.CCWPlugin
org.eclipse.core.runtime.jobs.Job
org.eclipse.core.runtime.IProgressMonitor))
org.eclipse.core.resources.IResource
org.eclipse.core.runtime.IProgressMonitor
org.osgi.service.prefs.BackingStoreException
org.eclipse.core.runtime.preferences.IEclipsePreferences))

(defvar- queued-commands (ref {})
"Map between project names and vectors of REPL expressions that have yet to
Expand All @@ -16,12 +20,13 @@
(defvar- persist-schedule-ms 30000
"Queued commands are persisted to project preferences every _ milliseconds.")

(defn- get-pref-node
(defn- ^IEclipsePreferences get-pref-node
[project-name]
(-?> project-name
ccw.launching.LaunchUtils/getProject
org.eclipse.core.resources.ProjectScope.
(.getNode pref-node-id)))
(.getNode pref-node-id)
(doto .sync)))

(defn- queue-expression
[project-name expr]
Expand Down Expand Up @@ -53,31 +58,52 @@
(partial queue-expression project-name)]
[[] identity])))

(defn- save-history
[project-name history]
(doto (get-pref-node project-name)
(.put history-key (pr-str history))
.flush))
(defn- save-cmds
[^IProgressMonitor pm queued-commands]
(loop [[[project-name exprs] & rqs :as queued-commands] (seq queued-commands)
retrying? false]
(when project-name
(let [[history] (get-history project-name)
node (get-pref-node project-name)
retry? (atom false)]
(.subTask pm project-name)
(try (doto node
(.put history-key (->> (reverse exprs)
(concat history)
(take-last max-history)
; prevent consecutive duplicate expressions
(partition-by identity)
(mapcat (partial take 1))
vec
pr-str))
.flush)
(catch BackingStoreException e
(if retrying?
(CCWPlugin/logError e)
(reset! retry? true))))
(if (not @retry?)
(recur rqs false)
(do
; maybe someone touched our project prefs; refresh
(CCWPlugin/log (format "Refreshing settings dir for %s, re-attempting saving REPL command history" project-name))
(-?> project-name
ccw.launching.LaunchUtils/getProject
(.getFolder ".settings")
(.refreshLocal IResource/DEPTH_INFINITE nil))
(recur queued-commands true)))))))

(defvar- save-cmds-job
(doto (proxy [Job] ["ccw REPL command history persistence"]
(run [^IProgressMonitor pm]
(.beginTask pm "Persisting REPL histories" IProgressMonitor/UNKNOWN)
(doseq [[project-name exprs] (dosync (let [queued @queued-commands]
(ref-set queued-commands {})
queued))
:let [[history] (get-history project-name)]]
(.subTask pm project-name)
(save-history project-name (->> (reverse exprs)
(concat history)
(take-last max-history)
; prevent consecutive duplicate expressions
(partition-by identity)
(mapcat (partial take 1))
vec)))
(.done pm)
(.schedule this persist-schedule-ms)
org.eclipse.core.runtime.Status/OK_STATUS))
(run [pm]
(try
(.beginTask pm "Persisting REPL histories" IProgressMonitor/UNKNOWN)
(save-cmds pm (dosync (let [queued (ensure queued-commands)]
(ref-set queued-commands {})
queued)))
(.done pm)
org.eclipse.core.runtime.Status/OK_STATUS
(finally
(.schedule this persist-schedule-ms)))))
(.setSystem true)))

(defn- schedule-job
Expand Down
10 changes: 5 additions & 5 deletions ccw.core/src/ccw/repl/view_helpers.clj
Expand Up @@ -76,11 +76,11 @@

(defn eval-expression
[repl-view log-component {:keys [send]} requests-atom expr]
(let [response-fn (send expr :ns (.getCurrentNamespace repl-view))
(let [response-fn (send expr :ns (.getCurrentNamespace repl-view) :timeout Long/MAX_VALUE)
key [(System/currentTimeMillis) expr]]
(swap! requests-atom assoc key response-fn)
(future (try
(doseq [{:keys [out err value ns status] :as resp} (repl/response-seq response-fn)]
(doseq [{:keys [out err value ns status] :as resp} (repl/response-seq response-fn Long/MAX_VALUE)]
(ui-sync
(when ns
; TODO: need to make sure that a response from an earlier request doesn't
Expand All @@ -92,7 +92,7 @@
(log log-component v k)
(CCWPlugin/log (str "Cannot handle REPL response: " k (pr-str resp)))))
(case status
("timeout" "interrupted") (log log-component (eval-failure-msg status out) :err)
("timeout" "interrupted") (log log-component (eval-failure-msg status expr) :err)
nil)))
(catch Throwable t
(CCWPlugin/logError (eval-failure-msg nil expr) t)
Expand Down Expand Up @@ -134,7 +134,6 @@
cursor-at-end)))))))

(comp (apply partial eval-expression args)
retain-expr-fn
(fn [expr add-to-log?]
(reset! retained-input nil)
(reset! current-step -1)
Expand All @@ -144,5 +143,6 @@
(if (= expr (last %))
%
(conj % expr))
(-> % count (- history/max-history) (max 0)))))
(-> % count (- history/max-history) (max 0))))
(retain-expr-fn expr))
expr))))

0 comments on commit 5b22def

Please sign in to comment.