spring-projects/spring-shell

Spring Shell ComponentFlow and locale

rugbroed opened this issue · 1 comments

I can't get Spring Shell to accept non-english characters (in my case, Danish).

To be precise; when the shell starts, I can input the danish characters æøå without problems in the shell itself (not running any commands, just typing the characters in the shell). But as soon as I want to input them using a ComponentFlow or StringInput getting the input text from a context, the keypresses are ignored and are not concatenated in the resulting string.

Can someone please help me figure out if there is a problem with non-english characters for input?

You can reproduce by making a simple ShellComponent with a ShellMethod and a ComponentFlow with a withStringInput and try to enter danish characters and see if you can get it from the context like this;

@ShellComponent
public class ProductCommand {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@ShellMethod(key = "test-locale")
	public String testLocale() {
		logger.info("Terminal is not null. Charset: " + terminal.encoding().displayName());

		ComponentFlow flow = componentFlowBuilder.clone()
				.withStringInput("testString")
				.name("Test string")
				.renderer(new StringInputCustomRenderer()).and().build();
		
	ComponentFlowResult result = flow.run();

	return "testString = " + result.getContext().get("testString");
}

The logger output is UTF-8, but I'm not able to input 'æøå' when running the test-locale command in the Test string prompt.

OR you can use the below instead;

StringInput component = new StringInput(terminal, "Test string", "testString", new StringInputCustomRenderer());
component.setResourceLoader(resourceLoader);
component.setTemplateExecutor(templateExecutor);
StringInputContext context = component.run(StringInputContext.empty());		

return context.getResultValue();
class StringInputCustomRenderer implements Function<StringInputContext, List<AttributedString>> {
	@Override
	public List<AttributedString> apply(StringInputContext context) {
		AttributedStringBuilder builder = new AttributedStringBuilder();
		builder.append(context.getName());
		builder.append(" ");
		if (context.getResultValue() != null) {
			builder.append(context.getResultValue());
		}
		else  {
			String input = context.getInput();
			if (StringUtils.hasText(input)) {
				builder.append(input);
			}
			else {
				builder.append("[Default " + context.getDefaultValue() + "]");
			}
		}
		return Arrays.asList(builder.toAttributedString());
	}
}

I'm using Ubuntu 24.04, Spring Boot Starter 3.3.2 and Spring Shell 3.3.1.

Thanks.

Fixed in #1115. Backported to 3.3.x and 3.2.x. You can try snapshots until there's a release.