diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/AnyToDisplayTextNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/AnyToDisplayTextNode.java index e0bed63431ab..d2391a655b63 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/AnyToDisplayTextNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/text/AnyToDisplayTextNode.java @@ -1,5 +1,7 @@ package org.enso.interpreter.node.expression.builtin.text; +import com.ibm.icu.text.BreakIterator; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -11,6 +13,7 @@ import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.text.util.TypeToDisplayTextNode; import org.enso.interpreter.runtime.data.text.Text; +import org.enso.polyglot.common_utils.Core_Text_Utils; @BuiltinMethod(type = "Any", name = "to_display_text") public abstract class AnyToDisplayTextNode extends Node { @@ -32,6 +35,22 @@ Text showExceptions( } } + @Specialization + Text convertText(Text self) { + final var limit = 80; + if (self.length() < limit) { + return self; + } else { + return takePrefix(self, limit); + } + } + + @CompilerDirectives.TruffleBoundary + private static Text takePrefix(Text self, final int limit) { + var prefix = Core_Text_Utils.take_prefix(self.toString(), limit); + return Text.create(prefix); + } + @Fallback Text doShowType(Object self, @Cached TypeToDisplayTextNode typeToDisplayTextNode) { return Text.create(typeToDisplayTextNode.execute(self)); diff --git a/lib/scala/common-polyglot-core-utils/src/main/java/org/enso/polyglot/common_utils/Core_Text_Utils.java b/lib/scala/common-polyglot-core-utils/src/main/java/org/enso/polyglot/common_utils/Core_Text_Utils.java index f2a692d84f6e..f1befe6264ca 100644 --- a/lib/scala/common-polyglot-core-utils/src/main/java/org/enso/polyglot/common_utils/Core_Text_Utils.java +++ b/lib/scala/common-polyglot-core-utils/src/main/java/org/enso/polyglot/common_utils/Core_Text_Utils.java @@ -3,6 +3,9 @@ import com.ibm.icu.text.BreakIterator; public class Core_Text_Utils { + private Core_Text_Utils() { + } + /** Computes the length of the string as the number of grapheme clusters it contains. */ public static int computeGraphemeLength(String text) { BreakIterator iter = BreakIterator.getCharacterInstance(); @@ -14,6 +17,17 @@ public static int computeGraphemeLength(String text) { return len; } + /** Returns a prefix of the string not exceeding the provided grapheme length. */ + public static String take_prefix(String str, long grapheme_length) { + BreakIterator iter = BreakIterator.getCharacterInstance(); + iter.setText(str); + if (iter.next(Math.toIntExact(grapheme_length)) == BreakIterator.DONE) { + return str; + } else { + return str.substring(0, iter.current()); + } + } + /** Pretty prints the string, escaping special characters. */ public static String prettyPrint(String str) { int len = str.length(); diff --git a/std-bits/base/src/main/java/org/enso/base/Text_Utils.java b/std-bits/base/src/main/java/org/enso/base/Text_Utils.java index 277b0a06814e..34654e262e07 100644 --- a/std-bits/base/src/main/java/org/enso/base/Text_Utils.java +++ b/std-bits/base/src/main/java/org/enso/base/Text_Utils.java @@ -277,13 +277,7 @@ public static long grapheme_length(String str) { /** Returns a prefix of the string not exceeding the provided grapheme length. */ public static String take_prefix(String str, long grapheme_length) { - BreakIterator iter = BreakIterator.getCharacterInstance(); - iter.setText(str); - if (iter.next(Math.toIntExact(grapheme_length)) == BreakIterator.DONE) { - return str; - } else { - return str.substring(0, iter.current()); - } + return Core_Text_Utils.take_prefix(str, grapheme_length); } /** Returns a suffix of the string not exceeding the provided grapheme length. */ diff --git a/test/Tests/src/Data/Text/Utils_Spec.enso b/test/Tests/src/Data/Text/Utils_Spec.enso index 5c98c5bf0bb8..671f06ff32ad 100644 --- a/test/Tests/src/Data/Text/Utils_Spec.enso +++ b/test/Tests/src/Data/Text/Utils_Spec.enso @@ -89,4 +89,27 @@ spec = Text_Utils.take_suffix (kshi+kshi+'a'+kshi) 2 . should_equal 'a'+kshi Text_Utils.take_suffix (kshi+kshi+'a'+kshi) 1 . should_equal kshi + Test.group "to_display_text" <| + Test.specify "simple conversion" <| + "Hello".to_display_text . should_equal "Hello" + + Test.specify "long text conversion" <| + long = "Hello World! ".repeat 1024 + disp = long.to_display_text + disp.length . should_equal 80 + disp.characters.take (First 5) . should_equal [ 'H', 'e', 'l', 'l', 'o' ] + disp.characters.take (Last 6) . should_equal ['l', 'd', '!', ' ', 'H', 'e'] + + Test.specify "grapheme 1 conversion" <| + txt = 'a\u0321\u0302'*100 + txt.to_display_text . should_equal 'a\u0321\u0302'*80 + + Test.specify "grapheme 2 conversion" <| + txt = '\u0915\u094D\u0937\u093F'*100 + txt.to_display_text . should_equal '\u0915\u094D\u0937\u093F'*80 + + Test.specify "grapheme 3 conversion" <| + txt = '\u{1F926}\u{1F3FC}\u200D\u2642\uFE0F'*100 + txt.to_display_text . should_equal '\u{1F926}\u{1F3FC}\u200D\u2642\uFE0F'*80 + main = Test_Suite.run_main spec