From 621850f4bcbc7713ee6574f05e3ab32ed3d4526e Mon Sep 17 00:00:00 2001 From: mattirn Date: Tue, 15 Oct 2019 18:42:31 +0200 Subject: [PATCH] TailTipWidgets: a few bug fixes and improvements --- .../main/java/org/jline/builtins/Widgets.java | 83 +++++++++++++------ .../test/java/org/jline/example/Example.java | 6 +- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/builtins/src/main/java/org/jline/builtins/Widgets.java b/builtins/src/main/java/org/jline/builtins/Widgets.java index 6a3d108aa..80090088e 100644 --- a/builtins/src/main/java/org/jline/builtins/Widgets.java +++ b/builtins/src/main/java/org/jline/builtins/Widgets.java @@ -9,6 +9,8 @@ package org.jline.builtins; import static org.jline.keymap.KeyMap.range; +import static org.jline.keymap.KeyMap.ctrl; +import static org.jline.keymap.KeyMap.alt; import java.security.InvalidParameterException; import java.util.ArrayList; @@ -70,8 +72,13 @@ public void callWidget(String name) { } public void executeWidget(String name) { - // this should be executed inside readLine()!!! - widget(name).apply(); + // WORK-AROUND + getKeyMap().bind(new Reference(name), alt(ctrl('X'))); + reader.runMacro(alt(ctrl('X'))); + // The line below should be executed inside readLine()!!! + // Create LineReader method executeWidget() maybe??? + // + // widget(name).apply(); } public void aliasWidget(String orig, String alias) { @@ -104,8 +111,8 @@ private Widget widget(String name) { return out; } - public KeyMap getKeyMap(String name) { - return reader.getKeyMaps().get(name); + public KeyMap getKeyMap() { + return reader.getKeyMaps().get(LineReader.MAIN); } public Buffer buffer() { @@ -172,11 +179,21 @@ public void initDescription(int size) { as.add(new AttributedString("")); } addDescription(as); + reader.runMacro(KeyMap.ctrl('M')); } else if (status != null) { - status.clear(); + if (size < 0) { + status.update(null); + reader.runMacro(KeyMap.ctrl('M')); + } else { + status.clear(); + } } } + public void destroyDescription() { + initDescription(-1); + } + /** * Creates and manages widgets that auto-closes, deletes and skips over matching delimiters intelligently. */ @@ -236,7 +253,7 @@ public AutopairWidgets(LineReader reader, boolean addCurlyBrackets) { addWidget(AP_BACKWARD_DELETE_CHAR, this::autopairDelete); addWidget(AP_TOGGLE, this::toggleKeyBindings); - KeyMap map = getKeyMap(LineReader.MAIN); + KeyMap map = getKeyMap(); for (Map.Entry p: pairs.entrySet()) { defaultBindings.put(p.getKey(), map.getBound(p.getKey())); if (!p.getKey().equals(p.getValue())) { @@ -258,8 +275,9 @@ public void disable() { } public boolean toggle() { + boolean before = enabled; executeWidget(AP_TOGGLE); - return enabled; + return !before; } /* @@ -318,7 +336,7 @@ private void customBindings() { if (ttActive) { callWidget(TT_TOGGLE); } - KeyMap map = getKeyMap(LineReader.MAIN); + KeyMap map = getKeyMap(); for (Map.Entry p: pairs.entrySet()) { map.bind(new Reference(AP_INSERT), p.getKey()); if (!p.getKey().equals(p.getValue())) { @@ -333,7 +351,7 @@ private void customBindings() { } private void defaultBindings() { - KeyMap map = getKeyMap(LineReader.MAIN); + KeyMap map = getKeyMap(); for (Map.Entry p: pairs.entrySet()) { map.bind(defaultBindings.get(p.getKey()), p.getKey()); if (!p.getKey().equals(p.getValue())) { @@ -566,6 +584,7 @@ public enum TipType { private Map tailTips = new HashMap<>(); private TipType tipType; private int descriptionSize = 0; + private boolean descriptionEnabled = true; /** * Creates tailtip widgets used in command line suggestions. Suggestions are created using a command @@ -623,13 +642,13 @@ public TailTipWidgets(LineReader reader, Map tailTips, int descr this.tailTips = new HashMap<>(tailTips); this.descriptionSize = descriptionSize; this.tipType = tipType; - initDescription(descriptionSize); addWidget(TT_ACCEPT_LINE, this::tailtipAcceptLine); addWidget("_tailtip-insert", this::tailtipInsert); addWidget("_tailtip-backward-delete-char", this::tailtipBackwardDelete); addWidget("_tailtip-delete-char", this::tailtipDelete); addWidget("_tailtip-expand-or-complete", this::tailtipComplete); - addWidget("tailtip-toggle", this::toggleKeyBindings); + addWidget("tailtip-window", this::toggleWindow); + addWidget(TT_TOGGLE, this::toggleKeyBindings); } public void setDescriptionSize(int descriptionSize) { @@ -665,7 +684,9 @@ public void disable() { } public void enable() { - customBindings(); + if (!enabled) { + toggleKeyBindings(); + } } /* @@ -726,18 +747,17 @@ private boolean doTailTip(String widget) { } else if (!prevChar().equals(" ")) { doTailTip = false; } - List desc = new ArrayList<>(); boolean clearTip = false; - if (tailTips.containsKey(bp.get(0))) { + if (bp.size() > 0 && tailTips.containsKey(bp.get(0))) { if (lastArg.startsWith("-")) { - desc = tailTips.get(bp.get(0)).getOptionDescription(lastArg); + doDescription(tailTips.get(bp.get(0)).getOptionDescription(lastArg)); } if (bpsize > 0 && doTailTip) { List params = tailTips.get(bp.get(0)).getArgsDesc(); setSuggestionType(tipType == TipType.COMPLETER ? SuggestionType.COMPLETER : SuggestionType.TAIL_TIP); if (bpsize - 1 < params.size()) { if (!lastArg.startsWith("-")) { - desc = params.get(bpsize - 1).getDescription(); + doDescription(params.get(bpsize - 1).getDescription()); } StringBuilder tip = new StringBuilder(); for (int i = bpsize - 1; i < params.size(); i++) { @@ -747,7 +767,7 @@ private boolean doTailTip(String widget) { setTailTip(tip.toString()); } else if (params.get(params.size() - 1).getName().charAt(0) == '[') { setTailTip(params.get(params.size() - 1).getName()); - desc = params.get(params.size() - 1).getDescription(); + doDescription(params.get(params.size() - 1).getDescription()); } } else if (doTailTip) { clearTip = true; @@ -761,13 +781,12 @@ private boolean doTailTip(String widget) { setSuggestionType(SuggestionType.COMPLETER); } } - doDescription(desc); } return true; } private void doDescription(List desc) { - if (descriptionSize == 0) { + if (descriptionSize == 0 || !descriptionEnabled) { return; } if (desc.isEmpty()) { @@ -789,18 +808,32 @@ private void doDescription(List desc) { } private boolean autopairEnabled() { - Binding binding = getKeyMap(LineReader.MAIN).getBound("("); + Binding binding = getKeyMap().getBound("("); if (binding instanceof Reference && ((Reference)binding).name().equals(AP_INSERT)) { return true; } return false; } + public boolean toggleWindow() { + descriptionEnabled = !descriptionEnabled; + if (descriptionEnabled) { + initDescription(descriptionSize); + } else { + destroyDescription(); + } + return true; + } + public boolean toggleKeyBindings() { if (enabled) { defaultBindings(); + destroyDescription(); } else { customBindings(); + if (descriptionEnabled) { + initDescription(descriptionSize); + } } return enabled; } @@ -817,7 +850,7 @@ private boolean defaultBindings() { aliasWidget("." + LineReader.BACKWARD_DELETE_CHAR, LineReader.BACKWARD_DELETE_CHAR); aliasWidget("." + LineReader.DELETE_CHAR, LineReader.DELETE_CHAR); aliasWidget("." + LineReader.EXPAND_OR_COMPLETE, LineReader.EXPAND_OR_COMPLETE); - KeyMap map = getKeyMap(LineReader.MAIN); + KeyMap map = getKeyMap(); map.bind(new Reference(LineReader.SELF_INSERT), " "); map.bind(new Reference(LineReader.SELF_INSERT), "="); map.bind(new Reference(LineReader.SELF_INSERT), "-"); @@ -841,7 +874,7 @@ private void customBindings() { aliasWidget("_tailtip-backward-delete-char", LineReader.BACKWARD_DELETE_CHAR); aliasWidget("_tailtip-delete-char", LineReader.DELETE_CHAR); aliasWidget("_tailtip-expand-or-complete", LineReader.EXPAND_OR_COMPLETE); - KeyMap map = getKeyMap(LineReader.MAIN); + KeyMap map = getKeyMap(); map.bind(new Reference("_tailtip-insert"), " "); map.bind(new Reference("_tailtip-insert"), "="); map.bind(new Reference("_tailtip-insert"), "-"); @@ -917,8 +950,8 @@ public List getOptionDescription(String opt) { if (optsDesc.containsKey(opt)) { out.add(new AttributedString(opt)); for (AttributedString as: optsDesc.get(opt)) { - AttributedStringBuilder asb = new AttributedStringBuilder(); - asb.append(" \t"); + AttributedStringBuilder asb = new AttributedStringBuilder().tabs(8); + asb.append("\t"); asb.append(as); out.add(asb.toAttributedString()); } @@ -927,7 +960,7 @@ public List getOptionDescription(String opt) { } else { for (Map.Entry> entry: optsDesc.entrySet()) { if (entry.getKey().startsWith(opt)) { - AttributedStringBuilder asb = new AttributedStringBuilder(); + AttributedStringBuilder asb = new AttributedStringBuilder().tabs(8); asb.append(entry.getKey()); asb.append("\t"); asb.append(entry.getValue().get(0)); diff --git a/builtins/src/test/java/org/jline/example/Example.java b/builtins/src/test/java/org/jline/example/Example.java index fe57192c3..72dd43346 100644 --- a/builtins/src/test/java/org/jline/example/Example.java +++ b/builtins/src/test/java/org/jline/example/Example.java @@ -356,7 +356,7 @@ public void complete(LineReader reader, ParsedLine line, List candida )) , new ArgDesc("param3", new ArrayList<>()) ), optDesc)); - TailTipWidgets tailtipWidgets = new TailTipWidgets(reader, tailTips, TipType.COMPLETER); + TailTipWidgets tailtipWidgets = new TailTipWidgets(reader, tailTips, 5, TipType.COMPLETER); if (timer) { Executors.newScheduledThreadPool(1) .scheduleAtFixedRate(() -> { @@ -516,7 +516,6 @@ else if ("autosuggestion".equals(pl.word())) { } else if (type.startsWith("tai")) { autosuggestionWidgets.disable(); tailtipWidgets.enable(); - tailtipWidgets.setDescriptionSize(5); if (pl.words().size() > 2) { String mode = pl.words().get(2).toLowerCase(); if (mode.startsWith("tai")) { @@ -545,9 +544,6 @@ else if ("autosuggestion".equals(pl.word())) { terminal.writer().println("Autosuggestion: " + reader.getAutosuggestion()); } } - if (!tailtipWidgets.isEnabled()) { - Status.getStatus(terminal).update(null); - } } else if ("help".equals(pl.word()) || "?".equals(pl.word())) { help();