InlineEdit: Support Emacs and Vim key maps
Change-Id: I980afc3848f267811ab5890f9447fba16beed5d4
This commit is contained in:
parent
8018fbbc1e
commit
c4e01806ff
@ -1339,6 +1339,7 @@ link:#edit-preferences-info[EditPreferencesInfo] entity.
|
||||
)]}'
|
||||
{
|
||||
"theme": "ECLIPSE",
|
||||
"key_map_type": "VIM",
|
||||
"tab_size": 4,
|
||||
"line_length": 80,
|
||||
"hide_top_menu": true,
|
||||
@ -1365,6 +1366,7 @@ link:#edit-preferences-info[EditPreferencesInfo] entity.
|
||||
|
||||
{
|
||||
"theme": "ECLIPSE",
|
||||
"key_map_type": "VIM",
|
||||
"tab_size": 4,
|
||||
"line_length": 80,
|
||||
"hide_top_menu": true,
|
||||
@ -1757,6 +1759,9 @@ preferences of a user.
|
||||
The CodeMirror theme. Currently only a subset of light and dark
|
||||
CodeMirror themes are supported. Light themes `DEFAULT`, `ECLIPSE`,
|
||||
`ELEGANT`, `NEAT`. Dark themes `MIDNIGHT`, `NIGHT`, `TWILIGHT`.
|
||||
|`key_map_type` ||
|
||||
The CodeMirror key map. Currently only a subset of key maps are
|
||||
supported: `DEFAULT`, `EMACS`, `VIM`.
|
||||
|`tab_size` ||
|
||||
Number of spaces that should be used to display one tab.
|
||||
|`line_length` ||
|
||||
|
@ -176,9 +176,6 @@ with thefollowing logic on click:
|
||||
** "save-when-file-was-changed" or
|
||||
** "close-when-no-changes"
|
||||
|
||||
* Allow to activate different key maps, supported by CM: Emacs, Sublime, Vim. Load key
|
||||
maps dynamically. Currently default mode is used.
|
||||
|
||||
* Implement conflict resolution during rebase of change edit using inline edit
|
||||
feature by creating new edit on top of current patch set with auto merge content
|
||||
|
||||
|
@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import com.google.gerrit.acceptance.AbstractDaemonTest;
|
||||
import com.google.gerrit.acceptance.RestResponse;
|
||||
import com.google.gerrit.extensions.client.EditPreferencesInfo;
|
||||
import com.google.gerrit.extensions.client.KeyMapType;
|
||||
import com.google.gerrit.extensions.client.Theme;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
@ -42,6 +43,7 @@ public class EditPreferencesIT extends AbstractDaemonTest {
|
||||
assertThat(out.syntaxHighlighting).isTrue();
|
||||
assertThat(out.hideLineNumbers).isNull();
|
||||
assertThat(out.theme).isEqualTo(Theme.DEFAULT);
|
||||
assertThat(out.keyMapType).isEqualTo(KeyMapType.DEFAULT);
|
||||
|
||||
// change some default values
|
||||
out.lineLength = 80;
|
||||
@ -52,6 +54,7 @@ public class EditPreferencesIT extends AbstractDaemonTest {
|
||||
out.syntaxHighlighting = false;
|
||||
out.hideLineNumbers = true;
|
||||
out.theme = Theme.TWILIGHT;
|
||||
out.keyMapType = KeyMapType.EMACS;
|
||||
|
||||
r = adminSession.put(endPoint, out);
|
||||
assertThat(r.getStatusCode()).isEqualTo(HttpStatus.SC_NO_CONTENT);
|
||||
@ -78,5 +81,6 @@ public class EditPreferencesIT extends AbstractDaemonTest {
|
||||
assertThat(out.syntaxHighlighting).isNull();
|
||||
assertThat(out.hideLineNumbers).isEqualTo(in.hideLineNumbers);
|
||||
assertThat(out.theme).isEqualTo(in.theme);
|
||||
assertThat(out.keyMapType).isEqualTo(in.keyMapType);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ public class EditPreferencesInfo {
|
||||
public Boolean syntaxHighlighting;
|
||||
public Boolean hideLineNumbers;
|
||||
public Theme theme;
|
||||
public KeyMapType keyMapType;
|
||||
|
||||
public static EditPreferencesInfo defaults() {
|
||||
EditPreferencesInfo i = new EditPreferencesInfo();
|
||||
@ -35,6 +36,7 @@ public class EditPreferencesInfo {
|
||||
i.syntaxHighlighting = true;
|
||||
i.hideLineNumbers = false;
|
||||
i.theme = Theme.DEFAULT;
|
||||
i.keyMapType = KeyMapType.DEFAULT;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
// Copyright (C) 2015 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.extensions.client;
|
||||
|
||||
public enum KeyMapType {
|
||||
DEFAULT,
|
||||
EMACS,
|
||||
VIM
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.client.account;
|
||||
|
||||
import com.google.gerrit.extensions.client.EditPreferencesInfo;
|
||||
import com.google.gerrit.extensions.client.KeyMapType;
|
||||
import com.google.gerrit.extensions.client.Theme;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
|
||||
@ -29,6 +30,7 @@ public class EditPreferences extends JavaScriptObject {
|
||||
p.syntaxHighlighting(in.syntaxHighlighting);
|
||||
p.hideLineNumbers(in.hideLineNumbers);
|
||||
p.theme(in.theme);
|
||||
p.keyMapType(in.keyMapType);
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -41,6 +43,7 @@ public class EditPreferences extends JavaScriptObject {
|
||||
p.syntaxHighlighting = syntaxHighlighting();
|
||||
p.hideLineNumbers = hideLineNumbers();
|
||||
p.theme = theme();
|
||||
p.keyMapType = keyMapType();
|
||||
}
|
||||
|
||||
public final void theme(Theme i) {
|
||||
@ -48,6 +51,11 @@ public class EditPreferences extends JavaScriptObject {
|
||||
}
|
||||
private final native void setThemeRaw(String i) /*-{ this.theme = i }-*/;
|
||||
|
||||
public final void keyMapType(KeyMapType i) {
|
||||
setkeyMapTypeRaw(i != null ? i.toString() : KeyMapType.DEFAULT.toString());
|
||||
}
|
||||
private final native void setkeyMapTypeRaw(String i) /*-{ this.key_map_type = i }-*/;
|
||||
|
||||
public final native void tabSize(int t) /*-{ this.tab_size = t }-*/;
|
||||
public final native void lineLength(int c) /*-{ this.line_length = c }-*/;
|
||||
public final native void hideTopMenu(boolean s) /*-{ this.hide_top_menu = s }-*/;
|
||||
@ -62,6 +70,12 @@ public class EditPreferences extends JavaScriptObject {
|
||||
}
|
||||
private final native String themeRaw() /*-{ return this.theme }-*/;
|
||||
|
||||
public final KeyMapType keyMapType() {
|
||||
String s = keyMapTypeRaw();
|
||||
return s != null ? KeyMapType.valueOf(s) : KeyMapType.DEFAULT;
|
||||
}
|
||||
private final native String keyMapTypeRaw() /*-{ return this.key_map_type }-*/;
|
||||
|
||||
public final int tabSize() {return get("tab_size", 8); }
|
||||
public final int lineLength() {return get("line_length", 100); }
|
||||
public final native boolean hideTopMenu() /*-{ return this.hide_top_menu || false }-*/;
|
||||
|
@ -20,6 +20,7 @@ import com.google.gerrit.client.account.AccountApi;
|
||||
import com.google.gerrit.client.account.EditPreferences;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.ui.NpIntTextBox;
|
||||
import com.google.gerrit.extensions.client.KeyMapType;
|
||||
import com.google.gerrit.extensions.client.Theme;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.event.dom.client.ChangeEvent;
|
||||
@ -61,6 +62,7 @@ class EditPreferencesBox extends Composite {
|
||||
@UiField ToggleButton whitespaceErrors;
|
||||
@UiField ToggleButton lineNumbers;
|
||||
@UiField ListBox theme;
|
||||
@UiField ListBox keyMap;
|
||||
@UiField Button apply;
|
||||
@UiField Button save;
|
||||
|
||||
@ -68,6 +70,7 @@ class EditPreferencesBox extends Composite {
|
||||
this.view = view;
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
initTheme();
|
||||
initKeyMapType();
|
||||
}
|
||||
|
||||
void set(EditPreferences prefs) {
|
||||
@ -81,6 +84,7 @@ class EditPreferencesBox extends Composite {
|
||||
whitespaceErrors.setValue(prefs.showWhitespaceErrors());
|
||||
lineNumbers.setValue(prefs.hideLineNumbers());
|
||||
setTheme(prefs.theme());
|
||||
setKeyMapType(prefs.keyMapType());
|
||||
}
|
||||
|
||||
@UiHandler("tabWidth")
|
||||
@ -150,6 +154,14 @@ class EditPreferencesBox extends Composite {
|
||||
});
|
||||
}
|
||||
|
||||
@UiHandler("keyMap")
|
||||
void onKeyMap(@SuppressWarnings("unused") ChangeEvent e) {
|
||||
KeyMapType keyMapType = KeyMapType.valueOf(
|
||||
keyMap.getValue(keyMap.getSelectedIndex()));
|
||||
prefs.keyMapType(keyMapType);
|
||||
view.getEditor().setOption("keyMap", keyMapType.name().toLowerCase());
|
||||
}
|
||||
|
||||
@UiHandler("apply")
|
||||
void onApply(@SuppressWarnings("unused") ClickEvent e) {
|
||||
close();
|
||||
@ -210,4 +222,27 @@ class EditPreferencesBox extends Composite {
|
||||
Theme.TWILIGHT.name().toLowerCase(),
|
||||
Theme.TWILIGHT.name());
|
||||
}
|
||||
|
||||
private void setKeyMapType(KeyMapType v) {
|
||||
String name = v != null ? v.name() : KeyMapType.DEFAULT.name();
|
||||
for (int i = 0; i < keyMap.getItemCount(); i++) {
|
||||
if (keyMap.getValue(i).equals(name)) {
|
||||
keyMap.setSelectedIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
keyMap.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
private void initKeyMapType() {
|
||||
keyMap.addItem(
|
||||
KeyMapType.DEFAULT.name().toLowerCase(),
|
||||
KeyMapType.DEFAULT.name());
|
||||
keyMap.addItem(
|
||||
KeyMapType.EMACS.name().toLowerCase(),
|
||||
KeyMapType.EMACS.name());
|
||||
keyMap.addItem(
|
||||
KeyMapType.VIM.name().toLowerCase(),
|
||||
KeyMapType.VIM.name());
|
||||
}
|
||||
}
|
||||
|
@ -165,6 +165,10 @@ limitations under the License.
|
||||
<th><ui:msg>Theme</ui:msg></th>
|
||||
<td><g:ListBox ui:field='theme'/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><ui:msg>Key Map</ui:msg></th>
|
||||
<td><g:ListBox ui:field='keyMap'/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><ui:msg>Tab Width</ui:msg></th>
|
||||
<td><x:NpIntTextBox ui:field='tabWidth'
|
||||
|
@ -44,6 +44,7 @@ import com.google.gerrit.client.ui.InlineHyperlink;
|
||||
import com.google.gerrit.client.ui.Screen;
|
||||
import com.google.gerrit.common.PageLinks;
|
||||
import com.google.gerrit.extensions.client.EditPreferencesInfo;
|
||||
import com.google.gerrit.extensions.client.KeyMapType;
|
||||
import com.google.gerrit.reviewdb.client.Patch;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
@ -257,11 +258,18 @@ public class EditScreen extends Screen {
|
||||
@Override
|
||||
public void registerKeys() {
|
||||
super.registerKeys();
|
||||
cm.addKeyMap(KeyMap.create()
|
||||
KeyMap localKeyMap = KeyMap.create();
|
||||
localKeyMap
|
||||
.on("Ctrl-L", gotoLine())
|
||||
.on("Cmd-L", gotoLine())
|
||||
.on("Cmd-S", save())
|
||||
.on("Ctrl-S", save()));
|
||||
.on("Cmd-S", save());
|
||||
|
||||
// TODO(davido): Find a better way to prevent key maps collisions
|
||||
if (prefs.keyMapType() != KeyMapType.EMACS) {
|
||||
localKeyMap.on("Ctrl-S", save());
|
||||
}
|
||||
|
||||
cm.addKeyMap(localKeyMap);
|
||||
}
|
||||
|
||||
private Runnable gotoLine() {
|
||||
@ -441,7 +449,7 @@ public class EditScreen extends Screen {
|
||||
.set("scrollbarStyle", "overlay")
|
||||
.set("styleSelectedText", true)
|
||||
.set("showTrailingSpace", prefs.showWhitespaceErrors())
|
||||
.set("keyMap", "default")
|
||||
.set("keyMap", prefs.keyMapType().name().toLowerCase())
|
||||
.set("theme", prefs.theme().name().toLowerCase())
|
||||
.set("mode", mode != null ? mode.mode() : null));
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ CM_JS = [
|
||||
'lib/codemirror.js',
|
||||
'mode/meta.js',
|
||||
'keymap/vim.js',
|
||||
'keymap/emacs.js',
|
||||
]
|
||||
|
||||
CM_ADDONS = [
|
||||
|
Loading…
Reference in New Issue
Block a user