Mudlet / Mudlet

⚔️ A cross-platform, open source, and super fast MUD client with scripting in Lua
https://mudlet.org
GNU General Public License v2.0
736 stars 268 forks source link

Support a "soft-wrap" mode, in addition to the current "hard-wrap" #4174

Closed eternaleye closed 1 week ago

eternaleye commented 4 years ago

Brief summary of issue / Description of requested feature:

When Mudlet performs client-side wrapping of long lines, it does so by altering the line itself to contain additional newlines. This occurs after trigger processing, but subsequent actions on the buffer - copying text, moveCursorUp(); deleteLine(), logs - show the wrapping. Furthermore, when a window is resized, text that was wrapped for the previous size either extends past the bounds of the console (and thus requires horizontal scrolling) or is wrapped too tightly, resulting in poor legibility.

If instead, consoles wrapped all lines at display time, and the buffer itself was permitted to keep lines long internally, several things would become much cleaner:

For backwards compatibility, this could be a mode that defaults to off for miniconsoles.

Steps to reproduce the issue / Reasons for adding feature:

  1. Receive a line longer than the current console width from the MUD, or echo a long line from Lua
  2. Resize the console, or attempt to delete that line once it is no longer the current line
  3. Regret
vadi2 commented 4 years ago

It's not something we're currently looking to do as that would be doubling the memory use, primarily. The benefits aren't all that great either:

Resizing a window would reflow text to fit it perfectly

That is true.

Logs would contain lines as sent from the MUD

Logging logs what you see on the screen after all the processing was done, that's a great feature.

Gagging a multi-line message with long lines would work properly from multi-line triggers

Triggers aren't affected by Mudlet's wrapping, and ideally you can set your game not to linewrap - so triggers see the one long line, but what you see on the screen is linewrapped.

eternaleye commented 4 years ago

Logging logs what you see on the screen after all the processing was done, that's a great feature.

I spoke imprecisely - what I mean is that, if a line was sent from the MUD as a single long line, then it makes sense to log it that way for the purposes of things like searching logs after the fact. If something says "the foo flails violently as you strike it", a line break between "flails" and "violently" can make it very difficult to find later.

Triggers aren't affected by Mudlet's wrapping, and ideally you can set your game not to linewrap - so triggers see the one long line, but what you see on the screen is linewrapped.

Triggers aren't, but deleteLine() is, which is the problem. I have several triggers structured something like:

regex_rule
line_separator(1)
regex_rule_for_very_long_line
line_separator(1)
regex_rule

with AND true, and delta = 2. For example, this trigger for the Aligned form "Anchor":

```xml Anchor Actualized 0 2 0 #ff0000 #ffff00 #000000 #000000 ^You concentrate on berthing (.*)\.$ 1 ^You concentrate on the precise location of (.*) body as though it were its berth and as though it were anchored here\. As you imagine this possible state of affairs, you wrap a thick rope of eideturgy through the environment that makes it so\.$ 1 ^A small (.*)-inscribed (.*) limestone disc appears in the air above (.*)\.$ 1 5 1 5 1 ```

Because deleteLine() (and moveCursorUp()) are affected by this splitting, the middle line is improperly deleted. Perhaps there's a better way to delete all of the matched lines of a multi-line trigger, but I'm not aware of it.

vadi2 commented 4 years ago

Hmm that's not the case! deleteLine() isn't affected by the wrapping either, it acts on what the trigger sees. If I trigger a line You see exits leading northeast, southwest, and west. and set the line wrapping to 10 characters, a single deleteLine() call will get rid of the 6 lines that would have been shown.

eternaleye commented 4 years ago

Er, I think you're misconstruing me.

All of this is with my main window set to 140 columns.

The MUD sends the following three separate lines:

The trigger in the "Details" above then matches these three lines as a set, using a multi-line AND trigger with delta = 2.

At that point, it runs the following:

for _ = 1,3 do
  deleteLine()
  moveCursorUp()
end

The line You concentrate on berthing your opponent. is not deleted; if the long (second) line is long enough, a prefix of it may also remain. I verified this today, with a freshly-built Mudlet from develop.

EDIT: Note that if it is the last line that is long, and the rest are short, everything works perfectly! This is very likely the behavior you were describing; it's just not the problem I'm faced with.

vadi2 commented 4 years ago

I see. Yep, in trying to delete lines that have already been processed, it is affected. When processing the current line though, it is not, which is what I was clearing up.

eternaleye commented 4 years ago

Yeah, I expected that to be the first interpretation of "deleting long lines", which is why I specifically said "Resize the console, or attempt to delete that line once it is no longer the current line" (emphasis added) as point 2 in the original issue description.

SlySven commented 4 years ago

🤔 TBH It would make some things easier if lines were only wrapped at the point they are displayed so as to fit on the current screen; the whole line wrapping code needs a big overhaul to handle "wide" characters (including some emojis). That would have the advantage that when the TConsole/TTextEdit that contains the text is resized the text can be rewrapped to fit...

vadi2 commented 3 years ago

One idea for supporting a better 'copy' that copies without wrapping is to store a flag per line - if true, the newline was inserted by wrapping. Delete it for the unaltered text. Idea from Lindsey at the MUD discord.

ZookaOnGit commented 1 week ago

no traction