/*
* SourceVimCommands.java
*
* Copyright (C) 2009-15 by RStudio, Inc.
*
* Unless you have received this program directly from RStudio pursuant
* to the terms of a commercial license agreement with RStudio, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.studio.client.workbench.views.source;
import org.rstudio.core.client.command.ShortcutViewer;
public class SourceVimCommands
{
public final native void save(Source source) /*-{
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("write", "w",
$entry(function(cm, params) {
source.@org.rstudio.studio.client.workbench.views.source.Source::saveActiveSourceDoc()();
})
);
}-*/;
public native final void selectTabIndex(Source source) /*-{
var Vim = $wnd.require("ace/keyboard/vim").CodeMirror.Vim;
for (var i = 1; i <= 100; i++) {
(function(i) {
Vim.defineEx("b" + i, "b" + i, $entry(function(cm, params) {
source.@org.rstudio.studio.client.workbench.views.source.Source::vimSetTabIndex(I)(i - 1);
}));
})(i);
}
var nextTab = $entry(function(cm, args, vim) {
source.@org.rstudio.studio.client.workbench.views.source.Source::nextTabWithWrap()();
});
Vim.defineAction("selectNextTab", nextTab);
Vim.mapCommand({
keys: "gt",
type: "action",
action: "selectNextTab",
isEdit: false,
context: "normal"
});
var prevTab = $entry(function(cm, args, vim) {
source.@org.rstudio.studio.client.workbench.views.source.Source::prevTabWithWrap()();
});
Vim.defineAction("selectPreviousTab", prevTab);
Vim.mapCommand({
keys: "gT",
type: "action",
action: "selectPreviousTab",
isEdit: false,
context: "normal"
});
}-*/;
public native final void selectNextTab(Source source) /*-{
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("bnext", "bn",
$entry(function(cm, params) {
source.@org.rstudio.studio.client.workbench.views.source.Source::onNextTab()();
})
);
}-*/;
public native final void selectPreviousTab(Source source) /*-{
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("bprev", "bp",
$entry(function(cm, params) {
source.@org.rstudio.studio.client.workbench.views.source.Source::onPreviousTab()();
})
);
}-*/;
public native final void closeActiveTab(Source source) /*-{
var callback = $entry(function(cm, params) {
var interactive = true;
if (params.argString && params.argString === "!")
interactive = false;
source.@org.rstudio.studio.client.workbench.views.source.Source::closeSourceDoc(Z)(interactive);
});
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("bdelete", "bd", callback);
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("quit", "q", callback);
}-*/;
public native final void closeAllTabs(Source source) /*-{
var callback = $entry(function(cm, params) {
var interactive = true;
if (params.argString && params.argString === "!")
interactive = false;
source.@org.rstudio.studio.client.workbench.views.source.Source::closeAllTabs(Z)(interactive);
});
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("qall", "qa", callback);
}-*/;
public native final void createNewDocument(Source source) /*-{
var callback = $entry(function(cm, params) {
// Handle 'e!'
if (params.argString && params.argString === "!")
source.@org.rstudio.studio.client.workbench.views.source.Source::revertActiveDocument()();
// Handle other editing targets
else if (params.args) {
if (params.args.length === 1) {
source.@org.rstudio.studio.client.workbench.views.source.Source::editFile(Ljava/lang/String;)(params.args[0]);
}
// TODO: on error?
} else {
source.@org.rstudio.studio.client.workbench.views.source.Source::onNewSourceDoc()();
}
});
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("badd", "bad", callback);
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("edit", "e", callback);
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("tabedit", "tabe", callback);
}-*/;
public native final void saveAndCloseActiveTab(Source source) /*-{
var callback = $entry(function(cm, params) {
source.@org.rstudio.studio.client.workbench.views.source.Source::saveAndCloseActiveSourceDoc()();
});
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("wq", "wq", callback);
}-*/;
public native final void readFile(Source source, String encoding) /*-{
var callback = $entry(function(cm, params) {
if (params.args && params.args.length === 1) {
source.@org.rstudio.studio.client.workbench.views.source.Source::pasteFileContentsAtCursor(Ljava/lang/String;Ljava/lang/String;)(params.args[0], encoding);
}
});
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("read", "r", callback);
}-*/;
public native final void runRScript(Source source) /*-{
var callback = $entry(function(cm, params) {
if (params.args) {
source.@org.rstudio.studio.client.workbench.views.source.Source::pasteRCodeExecutionResult(Ljava/lang/String;)(params.argString);
}
});
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("Rscript", "R", callback);
}-*/;
public native final void reflowText(Source source) /*-{
var Vim = $wnd.require("ace/keyboard/vim").CodeMirror.Vim;
var callback = $entry(function(cm, args, vim) {
source.@org.rstudio.studio.client.workbench.views.source.Source::reflowText()();
if (vim.visualMode)
Vim.exitVisualMode(cm, false);
});
Vim.defineAction("reflowText", callback);
Vim.mapCommand({
keys: "gq",
type: "action",
action: "reflowText",
isEdit: true,
context: "visual"
});
Vim.mapCommand({
keys: "gqq",
type: "action",
action: "reflowText",
isEdit: true,
context: "normal"
});
}-*/;
public native final void reindent(Source source) /*-{
var Vim = $wnd.require("ace/keyboard/vim").CodeMirror.Vim;
var callback = $entry(function(cm, args, vim) {
source.@org.rstudio.studio.client.workbench.views.source.Source::reindent()();
if (vim.visualMode)
Vim.exitVisualMode(cm, false);
});
Vim.defineAction("reindent", callback);
Vim.mapCommand({
keys: "==",
type: "action",
action: "reindent",
isEdit: true,
context: "normal"
});
Vim.mapCommand({
keys: "=",
type: "action",
action: "reindent",
isEdit: true,
context: "visual"
});
}-*/;
public native final void showHelpAtCursor(Source source) /*-{
var Vim = $wnd.require("ace/keyboard/vim").CodeMirror.Vim;
var callback = $entry(function(cm, args, vim) {
source.@org.rstudio.studio.client.workbench.views.source.Source::showHelpAtCursor()();
});
Vim.defineAction("showHelpAtCursor", callback);
Vim.mapCommand({
keys: "K",
type: "action",
action: "showHelpAtCursor",
isEdit: false,
context: "normal"
});
}-*/;
public native final void showVimHelp(ShortcutViewer viewer) /*-{
var callback = $entry(function(cm, params) {
viewer.@org.rstudio.core.client.command.ShortcutViewer::showVimKeyboardShortcuts()();
});
$wnd.require("ace/keyboard/vim").CodeMirror.Vim.defineEx("help", "help", callback);
}-*/;
public native final void expandShrinkSelection(Source source) /*-{
var Vim = $wnd.require("ace/keyboard/vim").CodeMirror.Vim;
function toVimSelection(range) {
return {
anchor: {
line: range.start.row, ch: range.start.column
},
head: {
line: range.end.row, ch: range.end.column - 1
}
};
}
var expandCallback = $entry(function(cm, origHead, motionArgs, vim) {
vim.sel = toVimSelection(cm.ace.$expandSelection());
});
Vim.defineMotion("expandSelection", expandCallback);
Vim.mapCommand({
keys: "v",
type: "motion",
motion: "expandSelection",
context: "visual"
});
var shrinkCallback = $entry(function(cm, origHead, motionArgs, vim) {
vim.sel = toVimSelection(cm.ace.$shrinkSelection());
});
Vim.defineMotion("shrinkSelection", shrinkCallback);
Vim.mapCommand({
keys: "V",
type: "motion",
motion: "shrinkSelection",
context: "visual"
});
}-*/;
public native final void addStarRegister() /*-{
var SystemClipboardRegister = function(text, linewise, blockwise) {
this.clear();
this.keyBuffer = [text || ''];
this.insertModeChanges = [];
this.searchQueries = [];
this.linewise = !!linewise;
this.blockwise = !!blockwise;
}
// TODO: Reimplement this and read/write
// from the system clipboard using appropriate
// callbacks.
SystemClipboardRegister.prototype = {
setText: function(text, linewise, blockwise) {
this.keyBuffer = [text || ''];
this.linewise = !!linewise;
this.blockwise = !!blockwise;
},
pushText: function(text, linewise) {
this.keyBuffer.push(text);
if (linewise) {
if (!this.linewise) {
this.keyBuffer.push('\n');
}
this.linewise = true;
}
this.keyBuffer.push(text);
},
clear: function() {
this.keyBuffer = [];
this.insertModeChanges = [];
this.searchQueries = [];
this.linewise = false;
},
toString: function() {
return this.keyBuffer.join('');
}
};
var Vim = $wnd.require("ace/keyboard/vim").CodeMirror.Vim;
var controller = Vim.getRegisterController();
// controller.registers['*'] = new SystemClipboardRegister();
}-*/;
}