Fix formatting of code longer than Discord's message limit#549
Fix formatting of code longer than Discord's message limit#549Neil-Tomar wants to merge 8 commits into
Conversation
danthe1st
left a comment
There was a problem hiding this comment.
Congratulations on writing your first pull request. I commented on a few things I noticed. Please don't unnecessarily duplicate code.
| } | ||
| channel.sendMessage(messages.get(index)) | ||
| .setAllowedMentions(List.of()) | ||
| .setComponents(FormatCodeCommand.buildActionRow(event.getTarget(), event.getUser().getIdLong())) |
There was a problem hiding this comment.
The action row including the buttons for deleting and the URL for jumping back are no longer present because you removed them here. Please add them to all messages.
There was a problem hiding this comment.
There is a reason for that. The buttons only affect the message they are attached to, so adding them to each message would only allow deletion of that specific message.
Adding buttons to every message would also introduce a visual break inside the code block, which could hurt readability, as shown in the screenshots.
If you'd prefer the buttons to appear only on the last message while still affecting the entire code block, I can look into implementing that. I'm not familiar with that approach yet, but I'm happy to investigate it.
Here is with buttons:
as you can see it's hard to read through indentation.
There was a problem hiding this comment.
If it is a single message, both buttons should definitely be there.
If it consists of multiple messages, at least the View Original button should be present in the last message. There could also be a delete button that deletes all codeblock messages on the last message (and the file upload message should also have both buttons).
| this.content = content; | ||
| } | ||
|
|
||
| public String getContent() { |
There was a problem hiding this comment.
I think getContent() and setLanguage are unused. If so, please remove them.
There was a problem hiding this comment.
getContent() is still present.
There was a problem hiding this comment.
getContent() in now being used in FormatCodeDispatcher at line 34 and 44.
|
Fixes #537 |
…nto fix/format-code-long-messages # Conflicts: # src/main/java/net/discordjug/javabot/systems/user_commands/format_code/Code.java # src/main/java/net/discordjug/javabot/systems/user_commands/format_code/FormatCodeDispatcher.java # src/main/java/net/discordjug/javabot/systems/user_commands/format_code/Language.java
danthe1st
left a comment
There was a problem hiding this comment.
These are mostly minor comments. Is there any good reason why users would want a file response in addition to the codeblocks?
|
|
||
| MessageChannel channel = target.getChannel(); | ||
|
|
||
| event.replyFiles(file) |
There was a problem hiding this comment.
What is the reason to reply with a file vs just using event.reply... on the first message and skipping the file?
At least if it's only a single chunk, there shouldn't be any file (but I think it's also better without a file with multiple messages).
Make sure to update the Javadoc accordingly.
There was a problem hiding this comment.
I tried dropping the file and replying with the first chunk as suggested, but it hits two problems:
Sending the chunks as plain messages with no reply leaves the interaction unacknowledged → "This application did not respond."
Replying with the first chunk does acknowledge it, but the reply renders as its own attributed block, separate from the follow-up messages, so the code gets split visually mid-block.

Replying with the file avoids both: it acknowledges the interaction, and since the reply is a file (not a chunk) the code-block messages stay uniform with no break — plus it's a clean, copyable full version that reads nicely on desktop. The file seemed like the most useful thing to put there.
So, my preference would actually be to keep the file for both the single- and multi-chunk cases — it gives a consistent experience either way. But if you'd rather it was gone, I'm happy to remove it for the single-chunk case (just reply with the one block directly), or if you have a different approach in mind, I'll gladly go with that.
There was a problem hiding this comment.
In that case, please replace it with an ephemeral response:
Responses.success(event, "Success", "The formatted message is being sent to this channel.").queue();(or similar)
There is no reason to clutter the public channel with the file.
| /** | ||
| * Fallback used when the language is unrecognised; renders as plain text. | ||
| */ | ||
| UNKNOWN("Unknown", "txt"); |
There was a problem hiding this comment.
If you are removing the replyFiles, I think you can change the "txt" to "" but it's fine if you don't.
There was a problem hiding this comment.
Overall, your PR looks pretty good.
During testing, I noticed that it's possible to send a single message that can result in a lot of individual (and big). As an example, you can generate the content of such a message with the following code:
System.out.println("{".repeat(30)+"\n"+"a\n".repeat(1000)+"}".repeat(30));Please add a limit to this. I don't want to have to clean that up without knowing the exact number (I think it is possible to trigger more than 500 messages with a single message that way). See the second review comment here for how to fix it.
| * human-readable {@link #displayName} to the {@link #discordName} tag Discord uses for | ||
| * syntax highlighting inside code blocks. | ||
| */ | ||
| public enum Language { |
There was a problem hiding this comment.
If you want to, you can also add JSON there but you don't need to by any means.
| return; | ||
| } | ||
|
|
||
| List<String> messages = code.toDiscordMessages(); |
There was a problem hiding this comment.
Please show an error if messages.size() > 5 instead of sending the code.
There was a problem hiding this comment.
I forgot to mention the following: If you are already at it, could you please also remove the Collections.reverse(messages); statement? That shouldn't be there (unrelated to your PR) and results in formatting the wrong message.
| class FormatCodeDispatcher { | ||
|
|
||
| /** | ||
| * The maximum number of code-block messages to post inline; longer code is sent only as a file. |
There was a problem hiding this comment.
Please update the Javadoc to say it shows an error in that situation.
Description of the Changes
The "Format Code" / "Format and Indent Code" message commands and the
/format-codeslash command failed when the target message was longer than Discord's 2000-character limit: the whole snippet was wrapped in a single code block and sent as one message, which Discord rejects — so the command silently did nothing.This PR splits the formatted output into chunks that each stay under the limit:
Codeclass splits content into ≤1980-character chunks (breaking on newlines where possible) and renders each as a code block.Languageenum +Language.fromString(...)maps the slash command'sformatoption to a code-fence tag.A follow-up PR will add the language-selection dropdown.