langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java
changeset 36990 ec0b843a7af5
parent 36718 bf40906bf49d
child 37640 42e5136a367c
equal deleted inserted replaced
36782:6072af7a98be 36990:ec0b843a7af5
    31 import java.util.EnumSet;
    31 import java.util.EnumSet;
    32 import java.util.HashMap;
    32 import java.util.HashMap;
    33 import java.util.List;
    33 import java.util.List;
    34 import java.util.Locale;
    34 import java.util.Locale;
    35 import java.util.Map;
    35 import java.util.Map;
    36 import java.util.function.Function;
       
    37 import java.util.regex.Matcher;
    36 import java.util.regex.Matcher;
    38 import java.util.regex.Pattern;
    37 import java.util.regex.Pattern;
    39 import java.util.stream.Stream;
       
    40 import static java.util.stream.Collectors.joining;
    38 import static java.util.stream.Collectors.joining;
    41 
    39 
    42 /**
    40 /**
    43  * Feedback customization support
    41  * Feedback customization support
    44  *
    42  *
   109         return new Setter(tool, at).setNewMode();
   107         return new Setter(tool, at).setNewMode();
   110     }
   108     }
   111 
   109 
   112     public boolean setPrompt(JShellTool tool, ArgTokenizer at) {
   110     public boolean setPrompt(JShellTool tool, ArgTokenizer at) {
   113         return new Setter(tool, at).setPrompt();
   111         return new Setter(tool, at).setPrompt();
   114     }
       
   115 
       
   116     public void printFeedbackHelp(JShellTool tool) {
       
   117         new Setter(tool, null).printFeedbackHelp();
       
   118     }
       
   119 
       
   120     public void printFormatHelp(JShellTool tool) {
       
   121         new Setter(tool, null).printFormatHelp();
       
   122     }
       
   123 
       
   124     public void printNewModeHelp(JShellTool tool) {
       
   125         new Setter(tool, null).printNewModeHelp();
       
   126     }
       
   127 
       
   128     public void printPromptHelp(JShellTool tool) {
       
   129         new Setter(tool, null).printPromptHelp();
       
   130     }
   112     }
   131 
   113 
   132     {
   114     {
   133         for (FormatCase e : EnumSet.allOf(FormatCase.class))
   115         for (FormatCase e : EnumSet.allOf(FormatCase.class))
   134             selectorMap.put(e.name().toLowerCase(Locale.US), e);
   116             selectorMap.put(e.name().toLowerCase(Locale.US), e);
   553         Setter(JShellTool tool, ArgTokenizer at) {
   535         Setter(JShellTool tool, ArgTokenizer at) {
   554             this.tool = tool;
   536             this.tool = tool;
   555             this.at = at;
   537             this.at = at;
   556         }
   538         }
   557 
   539 
   558         void hard(String format, Object... args) {
       
   559             tool.hard(format, args);
       
   560         }
       
   561 
       
   562         void hardrb(String key) {
       
   563             tool.hardrb(key);
       
   564         }
       
   565 
       
   566         <E extends Enum<E>> void hardEnums(EnumSet<E> es, Function<E, String> e2s) {
       
   567             hardPairs(es.stream(), ev -> ev.name().toLowerCase(Locale.US), e2s);
       
   568         }
       
   569 
       
   570         <T> void hardPairs(Stream<T> stream, Function<T, String> a, Function<T, String> b) {
       
   571             tool.hardPairs(stream, a, b);
       
   572         }
       
   573 
       
   574         void fluff(String format, Object... args) {
   540         void fluff(String format, Object... args) {
   575             tool.fluff(format, args);
   541             tool.fluff(format, args);
   576         }
   542         }
   577 
   543 
   578         void error(String format, Object... args) {
   544         void fluffmsg(String format, Object... args) {
   579             tool.error(format, args);
   545             tool.fluffmsg(format, args);
   580         }
   546         }
   581 
   547 
   582         void errorat(String format, Object... args) {
   548         void errorat(String messageKey, Object... args) {
   583             Object[] a2 = Arrays.copyOf(args, args.length + 1);
   549             Object[] a2 = Arrays.copyOf(args, args.length + 2);
   584             a2[args.length] = at.whole();
   550             a2[args.length] = "/set " + at.whole();
   585             tool.error(format + " -- /set %s", a2);
   551             tool.errormsg(messageKey, a2);
   586         }
       
   587 
       
   588         void fluffRaw(String format, Object... args) {
       
   589             tool.fluffRaw(format, args);
       
   590         }
   552         }
   591 
   553 
   592         // For /set prompt <mode> "<prompt>" "<continuation-prompt>"
   554         // For /set prompt <mode> "<prompt>" "<continuation-prompt>"
   593         boolean setPrompt() {
   555         boolean setPrompt() {
   594             Mode m = nextMode();
   556             Mode m = nextMode();
   595             String prompt = nextFormat();
   557             String prompt = nextFormat();
   596             String continuationPrompt = nextFormat();
   558             String continuationPrompt = nextFormat();
   597             if (valid) {
   559             if (valid) {
   598                 m.setPrompts(prompt, continuationPrompt);
   560                 m.setPrompts(prompt, continuationPrompt);
   599             } else {
   561             } else {
   600                 fluff("See '/help /set prompt' for help");
   562                 fluffmsg("jshell.msg.see", "/help /set prompt");
   601             }
   563             }
   602             return valid;
   564             return valid;
   603         }
   565         }
   604 
   566 
   605         // For /set newmode <new-mode> [command|quiet [<old-mode>]]
   567         // For /set newmode <new-mode> [command|quiet [<old-mode>]]
   606         boolean setNewMode() {
   568         boolean setNewMode() {
   607             String umode = at.next();
   569             String umode = at.next();
   608             if (umode == null) {
   570             if (umode == null) {
   609                 errorat("Expected new feedback mode");
   571                 errorat("jshell.err.feedback.expected.new.feedback.mode");
   610                 valid = false;
   572                 valid = false;
   611             }
   573             }
   612             if (modeMap.containsKey(umode)) {
   574             if (modeMap.containsKey(umode)) {
   613                 errorat("Expected a new feedback mode name. %s is a known feedback mode", umode);
   575                 errorat("jshell.err.feedback.expected.mode.name", umode);
   614                 valid = false;
   576                 valid = false;
   615             }
   577             }
   616             String[] fluffOpt = at.next("command", "quiet");
   578             String[] fluffOpt = at.next("command", "quiet");
   617             boolean fluff = fluffOpt == null || fluffOpt.length != 1 || "command".equals(fluffOpt[0]);
   579             boolean fluff = fluffOpt == null || fluffOpt.length != 1 || "command".equals(fluffOpt[0]);
   618             if (fluffOpt != null && fluffOpt.length != 1) {
   580             if (fluffOpt != null && fluffOpt.length != 1) {
   619                 errorat("Specify either 'command' or 'quiet'");
   581                 errorat("jshell.err.feedback.command.quiet");
   620                 valid = false;
   582                 valid = false;
   621             }
   583             }
   622             Mode om = null;
   584             Mode om = null;
   623             String omode = at.next();
   585             String omode = at.next();
   624             if (omode != null) {
   586             if (omode != null) {
   627             if (valid) {
   589             if (valid) {
   628                 Mode nm = (om != null)
   590                 Mode nm = (om != null)
   629                         ? new Mode(umode, fluff, om)
   591                         ? new Mode(umode, fluff, om)
   630                         : new Mode(umode, fluff);
   592                         : new Mode(umode, fluff);
   631                 modeMap.put(umode, nm);
   593                 modeMap.put(umode, nm);
   632                 fluff("Created new feedback mode: %s", nm.name);
   594                 fluffmsg("jshell.msg.feedback.new.mode", nm.name);
   633             } else {
   595             } else {
   634                 fluff("See '/help /set newmode' for help");
   596                 fluffmsg("jshell.msg.see", "/help /set newmode");
   635             }
   597             }
   636             return valid;
   598             return valid;
   637         }
   599         }
   638 
   600 
   639         // For /set feedback <mode>
   601         // For /set feedback <mode>
   640         boolean setFeedback() {
   602         boolean setFeedback() {
   641             Mode m = nextMode();
   603             Mode m = nextMode();
   642             if (valid && m != null) {
   604             if (valid && m != null) {
   643                 mode = m;
   605                 mode = m;
   644                 fluff("Feedback mode: %s", mode.name);
   606                 fluffmsg("jshell.msg.feedback.mode", mode.name);
   645             } else {
   607             } else {
   646                 fluff("See '/help /set feedback' for help");
   608                 fluffmsg("jshell.msg.see", "/help /set feedback");
   647             }
   609             }
   648             return valid;
   610             return valid;
   649         }
   611         }
   650 
   612 
   651         // For /set format <mode> "<format>" <selector>...
   613         // For /set format <mode> "<format>" <selector>...
   652         boolean setFormat() {
   614         boolean setFormat() {
   653             Mode m = nextMode();
   615             Mode m = nextMode();
   654             String field = at.next();
   616             String field = at.next();
   655             if (field == null || at.isQuoted()) {
   617             if (field == null || at.isQuoted()) {
   656                 errorat("Expected field name missing");
   618                 errorat("jshell.err.feedback.expected.field");
   657                 valid = false;
   619                 valid = false;
   658             }
   620             }
   659             String format = valid? nextFormat() : null;
   621             String format = valid? nextFormat() : null;
   660             String slRaw;
   622             String slRaw;
   661             List<SelectorList> slList = new ArrayList<>();
   623             List<SelectorList> slList = new ArrayList<>();
   673                                 sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
   635                                 sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
   674                                 sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
   636                                 sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
   675                                 format));
   637                                 format));
   676                 }
   638                 }
   677             } else {
   639             } else {
   678                 fluff("See '/help /set format' for help");
   640                 fluffmsg("jshell.msg.see", "/help /set format");
   679             }
   641             }
   680             return valid;
   642             return valid;
   681         }
   643         }
   682 
   644 
   683         Mode nextMode() {
   645         Mode nextMode() {
   685             return toMode(umode);
   647             return toMode(umode);
   686         }
   648         }
   687 
   649 
   688         Mode toMode(String umode) {
   650         Mode toMode(String umode) {
   689             if (umode == null) {
   651             if (umode == null) {
   690                 errorat("Expected a feedback mode");
   652                 errorat("jshell.err.feedback.expected.mode");
   691                 valid = false;
   653                 valid = false;
   692                 return null;
   654                 return null;
   693             }
   655             }
   694             Mode m = modeMap.get(umode);
   656             Mode m = modeMap.get(umode);
   695             if (m != null) {
   657             if (m != null) {
   703             if (matches.length == 1) {
   665             if (matches.length == 1) {
   704                 return matches[0];
   666                 return matches[0];
   705             } else {
   667             } else {
   706                 valid = false;
   668                 valid = false;
   707                 if (matches.length == 0) {
   669                 if (matches.length == 0) {
   708                     errorat("Does not match any current feedback mode: %s", umode);
   670                     errorat("jshell.err.feedback.does.not.match.mode", umode);
   709                 } else {
   671                 } else {
   710                     errorat("Matches more then one current feedback mode: %s", umode);
   672                     errorat("jshell.err.feedback.ambiguous.mode", umode);
   711                 }
   673                 }
   712                 fluff("The feedback mode should be one of the following:");
   674                 fluffmsg("jshell.msg.feedback.mode.following");
   713                 modeMap.keySet().stream()
   675                 modeMap.keySet().stream()
   714                         .forEach(mk -> fluff("   %s", mk));
   676                         .forEach(mk -> fluff("   %s", mk));
   715                 return null;
   677                 return null;
   716             }
   678             }
   717         }
   679         }
   718 
   680 
   719         // Test if the format string is correctly
   681         // Test if the format string is correctly
   720         final String nextFormat() {
   682         final String nextFormat() {
   721             String format = at.next();
   683             String format = at.next();
   722             if (format == null) {
   684             if (format == null) {
   723                 errorat("Expected format missing");
   685                 errorat("jshell.err.feedback.expected.format");
   724                 valid = false;
   686                 valid = false;
   725                 return null;
   687                 return null;
   726             }
   688             }
   727             if (!at.isQuoted()) {
   689             if (!at.isQuoted()) {
   728                 errorat("Format '%s' must be quoted", format);
   690                 errorat("jshell.err.feedback.must.be.quoted", format);
   729                 valid = false;
   691                 valid = false;
   730                 return null;
   692                 return null;
   731             }
   693             }
   732             return format;
   694             return format;
   733         }
   695         }
   746                     SelectorCollector<?> lastCollector = null;
   708                     SelectorCollector<?> lastCollector = null;
   747                     for (String as : s.split(",")) {
   709                     for (String as : s.split(",")) {
   748                         if (!as.isEmpty()) {
   710                         if (!as.isEmpty()) {
   749                             Selector<?> sel = selectorMap.get(as);
   711                             Selector<?> sel = selectorMap.get(as);
   750                             if (sel == null) {
   712                             if (sel == null) {
   751                                 errorat("Not a valid selector %s in %s", as, s);
   713                                 errorat("jshell.err.feedback.not.a.valid.selector", as, s);
   752                                 valid = false;
   714                                 valid = false;
   753                                 return;
   715                                 return;
   754                             }
   716                             }
   755                             SelectorCollector<?> collector = sel.collector(this);
   717                             SelectorCollector<?> collector = sel.collector(this);
   756                             if (lastCollector == null) {
   718                             if (lastCollector == null) {
   757                                 if (!collector.isEmpty()) {
   719                                 if (!collector.isEmpty()) {
   758                                     errorat("Selector kind in multiple sections of selector list %s in %s", as, s);
   720                                     errorat("jshell.err.feedback.multiple.sections", as, s);
   759                                     valid = false;
   721                                     valid = false;
   760                                     return;
   722                                     return;
   761                                 }
   723                                 }
   762                             } else if (collector != lastCollector) {
   724                             } else if (collector != lastCollector) {
   763                                 errorat("Different selector kinds in same sections of selector list %s in %s", as, s);
   725                                 errorat("jshell.err.feedback.different.selector.kinds", as, s);
   764                                 valid = false;
   726                                 valid = false;
   765                                 return;
   727                                 return;
   766                             }
   728                             }
   767                             collector.add(sel);
   729                             collector.add(sel);
   768                             lastCollector = collector;
   730                             lastCollector = collector;
   769                         }
   731                         }
   770                     }
   732                     }
   771                 }
   733                 }
   772             }
   734             }
   773         }
   735         }
   774 
       
   775         final void printFormatHelp() {
       
   776             hardrb("help.set.format");
       
   777             hardrb("help.set.format.case");
       
   778             hardEnums(EnumSet.allOf(FormatCase.class), ev -> ev.doc);
       
   779             hardrb("help.set.format.action");
       
   780             hardEnums(EnumSet.allOf(FormatAction.class), ev -> ev.doc);
       
   781             hardrb("help.set.format.when");
       
   782             hardEnums(EnumSet.allOf(FormatWhen.class), ev -> ev.doc);
       
   783             hardrb("help.set.format.resolve");
       
   784             hardEnums(EnumSet.allOf(FormatResolve.class), ev -> ev.doc);
       
   785             hardrb("help.set.format.unresolved");
       
   786             hardEnums(EnumSet.allOf(FormatUnresolved.class), ev -> ev.doc);
       
   787             hardrb("help.set.format.errors");
       
   788             hardEnums(EnumSet.allOf(FormatErrors.class), ev -> ev.doc);
       
   789             hardrb("help.set.format.end");
       
   790         }
       
   791 
       
   792         final void printFeedbackHelp() {
       
   793             hardrb("help.set.feedback");
       
   794             modeMap.keySet().stream()
       
   795                     .forEach(m -> hard("   %s", m));
       
   796         }
       
   797 
       
   798         final void printNewModeHelp() {
       
   799             hardrb("help.set.newmode");
       
   800         }
       
   801 
       
   802         final void printPromptHelp() {
       
   803             hardrb("help.set.prompt");
       
   804         }
       
   805     }
   736     }
   806 }
   737 }