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<>(); |
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 } |