Skip to content

Commit

Permalink
support for removing items from history
Browse files Browse the repository at this point in the history
  • Loading branch information
jjallaire committed May 17, 2011
1 parent acacbb0 commit f86b1b8
Show file tree
Hide file tree
Showing 14 changed files with 320 additions and 68 deletions.
12 changes: 11 additions & 1 deletion src/cpp/r/include/r/session/RConsoleHistory.hpp
Expand Up @@ -49,6 +49,13 @@ class ConsoleHistory : boost::noncopyable
public:
void setCapacity(int capacity);

void setCapacityFromRHistsize();

int capacity() const
{
return historyBuffer_.capacity();
}

void setRemoveDuplicates(bool removeDuplicates);

void add(const std::string& command);
Expand All @@ -63,7 +70,7 @@ class ConsoleHistory : boost::noncopyable

void clear();

void remove(int index);
void remove(const std::vector<int>& indexes);

void subset(int beginIndex, // inclusive
int endIndex, // exclusive,
Expand All @@ -79,6 +86,9 @@ class ConsoleHistory : boost::noncopyable
{
return onAdd_.connect(slot);
}

private:
void safeRemove(int index);

private:
bool removeDuplicates_;
Expand Down
4 changes: 1 addition & 3 deletions src/cpp/r/include/r/session/RSession.hpp
Expand Up @@ -50,8 +50,7 @@ struct ROptions
autoReloadSource(false),
shellEscape(false),
restoreWorkspace(true),
saveWorkspace(SA_SAVEASK),
consoleHistorySize(250)
saveWorkspace(SA_SAVEASK)
{
}
core::FilePath userHomePath;
Expand All @@ -71,7 +70,6 @@ struct ROptions
bool shellEscape;
bool restoreWorkspace;
SA_TYPE saveWorkspace;
int consoleHistorySize;
};

struct RInitInfo
Expand Down
37 changes: 33 additions & 4 deletions src/cpp/r/session/RConsoleHistory.cpp
Expand Up @@ -13,12 +13,15 @@

#include <r/session/RConsoleHistory.hpp>

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/tokenizer.hpp>

#include <core/Error.hpp>
#include <core/FilePath.hpp>
#include <core/FileSerializer.hpp>
#include <core/system/System.hpp>
#include <core/SafeConvert.hpp>

using namespace core;

Expand All @@ -34,14 +37,24 @@ ConsoleHistory& consoleHistory()
ConsoleHistory::ConsoleHistory()
: removeDuplicates_(true)
{
setCapacity(500);
setCapacity(512);
}

void ConsoleHistory::setCapacity(int capacity)
{
historyBuffer_.set_capacity(capacity);
}

void ConsoleHistory::setCapacityFromRHistsize()
{
std::string histSize = core::system::getenv("R_HISTSIZE");
if (!histSize.empty())
{
setCapacity(
safe_convert::stringTo<std::size_t>(histSize, capacity()));
}
}

void ConsoleHistory::setRemoveDuplicates(bool removeDuplicates)
{
removeDuplicates_ = removeDuplicates;
Expand Down Expand Up @@ -85,10 +98,20 @@ void ConsoleHistory::clear()
historyBuffer_.clear();
}

void ConsoleHistory::remove(int index)

void ConsoleHistory::remove(const std::vector<int>& indexes)
{
if (index >= 0 && index < (int)historyBuffer_.size())
historyBuffer_.erase(historyBuffer_.begin() + index);
// make a copy and sort descending
std::vector<int> sortedIndexes;
std::copy(indexes.begin(),
indexes.end(),
std::back_inserter(sortedIndexes));
std::sort(sortedIndexes.begin(), sortedIndexes.end(),std::greater<int>());

// remove them all
std::for_each(sortedIndexes.begin(),
sortedIndexes.end(),
boost::bind(&ConsoleHistory::safeRemove, this, _1));
}

void ConsoleHistory::subset(int beginIndex, // inclusive
Expand Down Expand Up @@ -152,6 +175,12 @@ Error ConsoleHistory::saveToFile(const FilePath& filePath) const
core::stringifyString);
}

void ConsoleHistory::safeRemove(int index)
{
if (index >= 0 && index < (int)historyBuffer_.size())
historyBuffer_.erase(historyBuffer_.begin() + index);
}

} // namespace session
} // namespace r

Expand Down
24 changes: 16 additions & 8 deletions src/cpp/r/session/RSession.cpp
Expand Up @@ -99,8 +99,16 @@ class SuppressOutputInScope
};


// R history file
const char * const kRHistory = ".Rhistory";
FilePath rHistoryFilePath()
{
std::string histFile = core::system::getenv("R_HISTFILE");
boost::algorithm::trim(histFile);
if (histFile.empty())
histFile = ".Rhistory";

return s_options.rHistoryDir().complete(histFile);
}


FilePath rSaveGlobalEnvironmentFilePath()
{
Expand Down Expand Up @@ -269,6 +277,9 @@ SEXP win32QuitHook(SEXP call, SEXP op, SEXP args, SEXP rho);
// one-time per session initialization
Error initialize()
{
// initialize console history capacity
r::session::consoleHistory().setCapacityFromRHistsize();

// install R tools
FilePath toolsFilePath = s_options.rSourcePath.complete("Tools.R");
Error error = r::sourceManager().sourceLocal(toolsFilePath);
Expand Down Expand Up @@ -339,7 +350,7 @@ Error initialize()
else
{
// restore console history
FilePath historyPath = s_options.rHistoryDir().complete(kRHistory);
FilePath historyPath = rHistoryFilePath();
error = consoleHistory().loadFromFile(historyPath, false);
if (error)
reportHistoryAccessError("read history from", historyPath, error);
Expand Down Expand Up @@ -902,7 +913,7 @@ void RCleanUp(SA_TYPE saveact, int status, int runLast)
// save history if we either always save history or saveact == SA_SAVE
if (s_options.alwaysSaveHistory() || saveact == SA_SAVE)
{
FilePath historyPath = s_options.rHistoryDir().complete(kRHistory);
FilePath historyPath = rHistoryFilePath();
Error error = consoleHistory().saveToFile(historyPath);
if (error)
reportHistoryAccessError("write history to", historyPath, error);
Expand Down Expand Up @@ -1059,10 +1070,7 @@ Error run(const ROptions& options, const RCallbacks& callbacks)

// set source reloading behavior
sourceManager().setAutoReload(options.autoReloadSource);

// set console history size
consoleHistory().setCapacity(options.consoleHistorySize);


// initialize suspended session path
FilePath userScratchPath = s_options.userScratchPath;
s_suspendedSessionPath = userScratchPath.complete("suspended-session");
Expand Down
8 changes: 6 additions & 2 deletions src/cpp/session/SessionMain.cpp
Expand Up @@ -324,6 +324,8 @@ void handleClientInit(const boost::function<void()>& initFunction,
json::Array historyArray;
r::session::consoleHistory().asJson(&historyArray);
sessionInfo["console_history"] = historyArray;
sessionInfo["console_history_capacity"] =
r::session::consoleHistory().capacity();

// client state
json::Object clientStateObject;
Expand Down Expand Up @@ -1267,7 +1269,10 @@ void rConsoleHistoryReset()
{
json::Array historyJson;
r::session::consoleHistory().asJson(&historyJson);
ClientEvent event(kConsoleResetHistory, historyJson);
json::Object resetJson;
resetJson["history"] = historyJson;
resetJson["preserve_ui_context"] = false;
ClientEvent event(kConsoleResetHistory, resetJson);
session::clientEventQueue().add(event);
}

Expand Down Expand Up @@ -1885,7 +1890,6 @@ int main (int argc, char * const argv[])
rOptions.serverMode = serverMode;
rOptions.autoReloadSource = options.autoReloadSource();
rOptions.shellEscape = options.rShellEscape();
rOptions.consoleHistorySize = 250;
rOptions.restoreWorkspace = userSettings().loadRData();
// save action
int saveAction = userSettings().saveAction();
Expand Down
41 changes: 28 additions & 13 deletions src/cpp/session/modules/SessionHistory.cpp
Expand Up @@ -359,28 +359,45 @@ Error getHistoryItems(const json::JsonRpcRequest& request,
return Success();
}

void enqueConsoleResetHistoryEvent(bool preserveUIContext)
{
json::Array historyJson;
r::session::consoleHistory().asJson(&historyJson);
json::Object resetJson;
resetJson["history"] = historyJson;
resetJson["preserve_ui_context"] = preserveUIContext;
ClientEvent event(client_events::kConsoleResetHistory, resetJson);
module_context::enqueClientEvent(event);
}

Error removeHistoryItems(const json::JsonRpcRequest& request,
json::JsonRpcResponse* pResponse)
{
// get indexes
json::Array indexesJson;
Error error = json::readParam(request.params, 0, &indexesJson);
json::Array bottomIndexesJson;
Error error = json::readParam(request.params, 0, &bottomIndexesJson);
if (error)
return error;

// convert to vector of ints and sort them (ascending)
// convert to top indexes
int historySize = r::session::consoleHistory().size();
std::vector<int> indexes;
for (std::size_t i=0; i<indexesJson.size(); i++)
{
const json::Value& value = indexesJson[i];
for (std::size_t i=0; i<bottomIndexesJson.size(); i++)
{
const json::Value& value = bottomIndexesJson[i];
if (json::isType<int>(value))
indexes.push_back(value.get_int());
{
int bottomIndex = value.get_int();
int topIndex = historySize - 1 - bottomIndex;
indexes.push_back(topIndex);
}
}
std::sort(indexes.begin(), indexes.end());

// remove the indexes in reverse order (so removal doesn't affect
// the validity of the other indexes)
// remove them
r::session::consoleHistory().remove(indexes);

// enque event
enqueConsoleResetHistoryEvent(true);

return Success();
}
Expand All @@ -390,9 +407,7 @@ Error clearHistory(const json::JsonRpcRequest& request,
{
r::session::consoleHistory().clear();

json::Array historyJson;
ClientEvent event(client_events::kConsoleResetHistory, historyJson);
module_context::enqueClientEvent(event);
enqueConsoleResetHistoryEvent(false);

return Success();
}
Expand Down
24 changes: 24 additions & 0 deletions src/gwt/src/org/rstudio/core/client/widget/FastSelectTable.java
Expand Up @@ -312,7 +312,31 @@ public void clear()
table_.setInnerText("");
selectedRows_.clear();
}

// TODO: handle physical to logical
public int getRowCount()
{
return table_.getRows().getLength();
}

// TODO: handle physical to logical
public void removeTopRow()
{
setSelected(0, 1, false);
table_.getRows().getItem(0).removeFromParent();
}

// TODO: handle physical to logical
public ArrayList<Integer> getSelectedRowIndexes()
{
sortSelectedRows();

ArrayList<Integer> results = new ArrayList<Integer>();
for (TableRowElement row : selectedRows_)
results.add(row.getRowIndex());
return results;
}

private boolean isSelected(TableRowElement tr)
{
return tr.getClassName().contains(selectedClassName_);
Expand Down
Expand Up @@ -15,7 +15,6 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ClosingEvent;
Expand All @@ -39,6 +38,7 @@
import org.rstudio.studio.client.workbench.views.choosefile.events.ChooseFileEvent;
import org.rstudio.studio.client.workbench.views.console.events.*;
import org.rstudio.studio.client.workbench.views.console.model.ConsolePrompt;
import org.rstudio.studio.client.workbench.views.console.model.ConsoleResetHistory;
import org.rstudio.studio.client.workbench.views.data.events.ViewDataEvent;
import org.rstudio.studio.client.workbench.views.data.model.DataView;
import org.rstudio.studio.client.workbench.views.edit.events.ShowEditorEvent;
Expand Down Expand Up @@ -553,8 +553,8 @@ else if (type.equals(ClientEvent.Locator))
}
else if (type.equals(ClientEvent.ConsoleResetHistory))
{
JsArrayString history = event.getData();
eventBus.fireEvent(new ConsoleResetHistoryEvent(history));
ConsoleResetHistory reset = event.getData();
eventBus.fireEvent(new ConsoleResetHistoryEvent(reset));
}
else if (type.equals(ClientEvent.SessionSerialization))
{
Expand Down
Expand Up @@ -77,6 +77,10 @@ public final native String getDefaultPrompt() /*-{
public final native JsArrayString getConsoleHistory() /*-{
return this.console_history;
}-*/;

public final native int getConsoleHistoryCapacity() /*-{
return this.console_history_capacity;
}-*/;

public final native RpcObjectList<ConsoleAction> getConsoleActions() /*-{
return this.console_actions;
Expand Down
Expand Up @@ -12,6 +12,8 @@
*/
package org.rstudio.studio.client.workbench.views.console.events;

import org.rstudio.studio.client.workbench.views.console.model.ConsoleResetHistory;

import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.event.shared.GwtEvent;

Expand All @@ -20,14 +22,19 @@ public class ConsoleResetHistoryEvent extends GwtEvent<ConsoleResetHistoryHandle
public static final GwtEvent.Type<ConsoleResetHistoryHandler> TYPE =
new GwtEvent.Type<ConsoleResetHistoryHandler>();

public ConsoleResetHistoryEvent(JsArrayString history)
public ConsoleResetHistoryEvent(ConsoleResetHistory reset)
{
history_ = history;
reset_ = reset;
}

public JsArrayString getHistory()
{
return history_;
return reset_.getHistory();
}

public boolean getPreserveUIContext()
{
return reset_.getPreserveUIContext();
}

@Override
Expand All @@ -42,5 +49,5 @@ public GwtEvent.Type<ConsoleResetHistoryHandler> getAssociatedType()
return TYPE;
}

private final JsArrayString history_;
private final ConsoleResetHistory reset_;
}

0 comments on commit f86b1b8

Please sign in to comment.