SideBySide2: Allow the user to select the syntax highlighter

This can be useful if Gerrit does not magically recognize a
particular file format. Temporarily forcing on a single mode
may make it easier to review the file.

Change-Id: I61af2841bdc76cb29b124f10b0946b39c804d823
This commit is contained in:
Shawn Pearce
2014-04-25 16:16:31 -07:00
parent 5b35f87dd9
commit a00346bd7a
4 changed files with 99 additions and 0 deletions

View File

@@ -32,6 +32,8 @@ import com.google.gerrit.reviewdb.client.AccountDiffPreference;
import com.google.gerrit.reviewdb.client.AccountDiffPreference.Theme;
import com.google.gerrit.reviewdb.client.AccountDiffPreference.Whitespace;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyDownEvent;
@@ -52,6 +54,12 @@ import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ToggleButton;
import net.codemirror.lib.ModeInjector;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/** Displays current diff preferences. */
class PreferencesBox extends Composite {
interface Binder extends UiBinder<HTMLPanel, PreferencesBox> {}
@@ -83,6 +91,7 @@ class PreferencesBox extends Composite {
@UiField ToggleButton expandAllComments;
@UiField ToggleButton renderEntireFile;
@UiField ListBox theme;
@UiField ListBox mode;
@UiField Button apply;
@UiField Button save;
@@ -92,6 +101,7 @@ class PreferencesBox extends Composite {
initWidget(uiBinder.createAndBindUi(this));
initIgnoreWhitespace();
initTheme();
initMode();
}
@Override
@@ -146,6 +156,11 @@ class PreferencesBox extends Composite {
renderEntireFile.setEnabled(view.canEnableRenderEntireFile(prefs));
setTheme(prefs.theme());
mode.setEnabled(prefs.syntaxHighlighting());
if (prefs.syntaxHighlighting()) {
setMode(view.getContentType());
}
switch (view.getIntraLineStatus()) {
case OFF:
case OK:
@@ -288,9 +303,35 @@ class PreferencesBox extends Composite {
@UiHandler("syntaxHighlighting")
void onSyntaxHighlighting(ValueChangeEvent<Boolean> e) {
prefs.syntaxHighlighting(e.getValue());
mode.setEnabled(prefs.syntaxHighlighting());
if (prefs.syntaxHighlighting()) {
setMode(view.getContentType());
}
view.setSyntaxHighlighting(prefs.syntaxHighlighting());
}
@UiHandler("mode")
void onMode(ChangeEvent e) {
final String m = mode.getValue(mode.getSelectedIndex());
prefs.syntaxHighlighting(true);
syntaxHighlighting.setValue(true, false);
Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
@Override
public boolean execute() {
if (prefs.syntaxHighlighting() && view.isAttached()) {
view.operation(new Runnable() {
@Override
public void run() {
view.getCmFromSide(DisplaySide.A).setOption("mode", m);
view.getCmFromSide(DisplaySide.B).setOption("mode", m);
}
});
}
return false;
}
}, 50);
}
@UiHandler("whitespaceErrors")
void onWhitespaceErrors(ValueChangeEvent<Boolean> e) {
prefs.showWhitespaceErrors(e.getValue());
@@ -385,6 +426,51 @@ class PreferencesBox extends Composite {
IGNORE_ALL_SPACE.name());
}
private static final Map<String, String> NAME_TO_MODE;
private static final Map<String, String> NORMALIZED_MODES;
static {
NAME_TO_MODE = new TreeMap<String, String>();
NORMALIZED_MODES = new HashMap<String, String>();
for (String type : ModeInjector.getKnownMimeTypes()) {
String name = type;
if (name.startsWith("text/x-")) {
name = name.substring("text/x-".length());
} else if (name.startsWith("text/")) {
name = name.substring("text/".length());
} else if (name.startsWith("application/")) {
name = name.substring("application/".length());
}
String normalized = NAME_TO_MODE.get(name);
if (normalized == null) {
normalized = type;
NAME_TO_MODE.put(name, normalized);
}
NORMALIZED_MODES.put(type, normalized);
}
}
private void initMode() {
for (Map.Entry<String, String> e : NAME_TO_MODE.entrySet()) {
mode.addItem(e.getKey(), e.getValue());
}
}
private void setMode(String modeType) {
if (modeType != null && !modeType.isEmpty()) {
if (NORMALIZED_MODES.containsKey(modeType)) {
modeType =NORMALIZED_MODES.get(modeType);
}
for (int i = 0; i < mode.getItemCount(); i++) {
if (mode.getValue(i).equals(modeType)) {
mode.setSelectedIndex(i);
return;
}
}
}
mode.setSelectedIndex(0);
}
private void setTheme(Theme v) {
String name = v != null ? v.name() : Theme.DEFAULT.name();
for (int i = 0; i < theme.getItemCount(); i++) {

View File

@@ -203,6 +203,10 @@ limitations under the License.
<g:downFace><ui:msg>Show</ui:msg></g:downFace>
</g:ToggleButton></td>
</tr>
<tr>
<th><ui:msg>Language</ui:msg></th>
<td><g:ListBox ui:field='mode'/></td>
</tr>
<tr>
<th><ui:msg>Whitespace Errors</ui:msg></th>
<td><g:ToggleButton ui:field='whitespaceErrors'>

View File

@@ -591,6 +591,10 @@ public class SideBySide2 extends Screen {
|| (prefs.context() != WHOLE_FILE_CONTEXT && prefs.context() < 100);
}
String getContentType() {
return getContentType(diff.meta_b());
}
void setThemeStyles(boolean d) {
if (d) {
diffTable.addStyleName(DiffTable.style.dark());

View File

@@ -21,6 +21,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import net.codemirror.mode.Modes;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -94,6 +95,10 @@ public class ModeInjector {
return real != null ? real : mode;
}
public static Collection<String> getKnownMimeTypes() {
return mimeModes.keySet();
}
private static native boolean isModeLoaded(String n)
/*-{ return $wnd.CodeMirror.modes.hasOwnProperty(n); }-*/;