1
0
Fork 0
mirror of https://github.com/fluffle/goirc synced 2025-07-01 02:53:53 +00:00

Split long messages at a configurable length. Fixes #29.

This commit is contained in:
Alex Bramley 2013-03-17 01:21:09 +00:00
parent 0b64613fe3
commit 5c56572b0d
3 changed files with 146 additions and 12 deletions

View file

@ -38,6 +38,46 @@ func cutNewLines(s string) string {
return r[0]
}
// indexFragment looks for the last sentence split-point (defined as one of
// the punctuation characters .:;,!?"' followed by a space) in the string s
// and returns the index in the string after that split-point. If no split-
// point is found it returns the index after the last space in s, or -1.
func indexFragment(s string) int {
max := -1
for _, sep := range []string{". ", ": ", "; ", ", ", "! ", "? ", "\" ", "' "} {
if idx := strings.LastIndex(s, sep); idx > max {
max = idx
}
}
if max > 0 {
return max + 2
}
if idx := strings.LastIndex(s, " "); idx > 0 {
return idx + 1
}
return -1
}
// splitMessage splits a message > splitLen chars at:
// 1. the end of the last sentence fragment before splitLen
// 2. the end of the last word before splitLen
// 3. splitLen itself
func splitMessage(msg string, splitLen int) (msgs []string) {
// This is quite short ;-)
if splitLen < 10 {
splitLen = 10
}
for len(msg) > splitLen {
idx := indexFragment(msg[:splitLen])
if idx < 0 {
idx = splitLen
}
msgs = append(msgs, msg[:idx] + "...")
msg = msg[idx:]
}
return append(msgs, msg)
}
// Raw() sends a raw line to the server, should really only be used for
// debugging purposes but may well come in handy.
func (conn *Conn) Raw(rawline string) {
@ -93,29 +133,42 @@ func (conn *Conn) Whois(nick string) { conn.Raw(WHOIS + " " + nick) }
func (conn *Conn) Who(nick string) { conn.Raw(WHO + " " + nick) }
// Privmsg() sends a PRIVMSG to the target t
func (conn *Conn) Privmsg(t, msg string) { conn.Raw(PRIVMSG + " " + t + " :" + msg) }
func (conn *Conn) Privmsg(t, msg string) {
for _, s := range splitMessage(msg, conn.cfg.SplitLen) {
conn.Raw(PRIVMSG + " " + t + " :" + s)
}
}
// Notice() sends a NOTICE to the target t
func (conn *Conn) Notice(t, msg string) { conn.Raw(NOTICE + " " + t + " :" + msg) }
func (conn *Conn) Notice(t, msg string) {
for _, s := range splitMessage(msg, conn.cfg.SplitLen) {
conn.Raw(NOTICE + " " + t + " :" + s)
}
}
// Ctcp() sends a (generic) CTCP message to the target t
// with an optional argument
func (conn *Conn) Ctcp(t, ctcp string, arg ...string) {
msg := strings.Join(arg, " ")
if msg != "" {
msg = " " + msg
// We need to split again here to ensure
for _, s := range splitMessage(strings.Join(arg, " "), conn.cfg.SplitLen) {
if s != "" {
s = " " + s
}
// Using Raw rather than PRIVMSG here to avoid double-split problems.
conn.Raw(PRIVMSG + " " + t + " :\001" + strings.ToUpper(ctcp) + s + "\001")
}
conn.Privmsg(t, "\001"+strings.ToUpper(ctcp)+msg+"\001")
}
// CtcpReply() sends a generic CTCP reply to the target t
// with an optional argument
func (conn *Conn) CtcpReply(t, ctcp string, arg ...string) {
msg := strings.Join(arg, " ")
if msg != "" {
msg = " " + msg
for _, s := range splitMessage(strings.Join(arg, " "), conn.cfg.SplitLen) {
if s != "" {
s = " " + s
}
// Using Raw rather than NOTICE here to avoid double-split problems.
conn.Raw(NOTICE + " " + t + " :\001" + strings.ToUpper(ctcp) + s + "\001")
}
conn.Notice(t, "\001"+strings.ToUpper(ctcp)+msg+"\001")
}
// Version() sends a CTCP "VERSION" to the target t