From d847d55c06c9f1ec5658887da19bf6f2d7417a4c Mon Sep 17 00:00:00 2001 From: Daniel Oaks Date: Tue, 9 May 2017 21:09:44 +1000 Subject: [PATCH] Fix wordWrap function so it doesn't drop chars, and fix client.Notice() to automagically split very long lines. --- irc/client.go | 11 +++++++++-- irc/server.go | 23 ++++++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/irc/client.go b/irc/client.go index a2e33d46..079a049a 100644 --- a/irc/client.go +++ b/irc/client.go @@ -623,7 +623,14 @@ func (client *Client) Send(tags *map[string]ircmsg.TagValue, prefix string, comm } // Notice sends the client a notice from the server. -//TODO(dan): Make this handle message splitting. func (client *Client) Notice(text string) { - client.Send(nil, client.server.name, "NOTICE", client.nick, text) + limit := 400 + if client.capabilities[MaxLine] { + limit = client.server.limits.LineLen.Rest - 110 + } + lines := wordWrap(text, limit) + + for _, line := range lines { + client.Send(nil, client.server.name, "NOTICE", client.nick, line) + } } diff --git a/irc/server.go b/irc/server.go index d8c7008a..9079f9cb 100644 --- a/irc/server.go +++ b/irc/server.go @@ -886,30 +886,43 @@ func topicHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { return false } +// wordWrap wraps the given text into a series of lines that don't exceed lineWidth characters. func wordWrap(text string, lineWidth int) []string { var lines []string var cacheLine, cacheWord string for _, char := range text { - if (char == ' ' || char == '-') && len(cacheLine)+len(cacheWord)+1 < lineWidth { + if char == '\r' { + continue + } else if char == '\n' { + cacheLine += cacheWord + lines = append(lines, cacheLine) + cacheWord = "" + cacheLine = "" + } else if (char == ' ' || char == '-') && len(cacheLine)+len(cacheWord)+1 < lineWidth { + // natural word boundary cacheLine += cacheWord + string(char) cacheWord = "" - } else if len(cacheLine)+len(cacheWord)+1 >= lineWidth { + } else if lineWidth <= len(cacheLine)+len(cacheWord)+1 { + // time to wrap to next line if len(cacheLine) < (lineWidth / 2) { - // there must be a really long word or something, just split on word boundary + // this word takes up more than half a line... just split in the middle of the word cacheLine += cacheWord + string(char) cacheWord = "" + } else { + cacheWord += string(char) } lines = append(lines, cacheLine) cacheLine = "" } else { + // normal character cacheWord += string(char) } } - if len(cacheWord) > 0 { + if 0 < len(cacheWord) { cacheLine += cacheWord } - if len(cacheLine) > 0 { + if 0 < len(cacheLine) { lines = append(lines, cacheLine) }