func (conn *Conn) Cap(subcommmand string, capabilities ...string) {
	if len(capabilities) == 0 {
		conn.Raw(CAP + " " + subcommmand)
	} else {
		conn.Raw(CAP + " " + subcommmand + " :" + strings.Join(capabilities, " "))
	}
}
Cap sends a CAP command to the server.
CAP subcommand
CAP subcommand :message
package client
import (
	"fmt"
	"strings"
)
const (
	REGISTER     = "REGISTER"
	CONNECTED    = "CONNECTED"
	DISCONNECTED = "DISCONNECTED"
	ACTION       = "ACTION"
	AWAY         = "AWAY"
	CAP          = "CAP"
	CTCP         = "CTCP"
	CTCPREPLY    = "CTCPREPLY"
	ERROR        = "ERROR"
	INVITE       = "INVITE"
	JOIN         = "JOIN"
	KICK         = "KICK"
	MODE         = "MODE"
	NICK         = "NICK"
	NOTICE       = "NOTICE"
	OPER         = "OPER"
	PART         = "PART"
	PASS         = "PASS"
	PING         = "PING"
	PONG         = "PONG"
	PRIVMSG      = "PRIVMSG"
	QUIT         = "QUIT"
	TOPIC        = "TOPIC"
	USER         = "USER"
	VERSION      = "VERSION"
	VHOST        = "VHOST"
	WHO          = "WHO"
	WHOIS        = "WHOIS"
	defaultSplit = 450
)
func cutNewLines(s string) string {
	r := strings.SplitN(s, "\r", 2)
	r = strings.SplitN(r[0], "\n", 2)
	return r[0]
}
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
}
func splitMessage(msg string, splitLen int) (msgs []string) {
	if splitLen < 13 {
		splitLen = defaultSplit
	}
	for len(msg) > splitLen {
		idx := indexFragment(msg[:splitLen-3])
		if idx < 0 {
			idx = splitLen - 3
		}
		msgs = append(msgs, msg[:idx]+"...")
		msg = msg[idx:]
	}
	return append(msgs, msg)
}
func (conn *Conn) Raw(rawline string) {
	conn.out <- cutNewLines(rawline)
}
func (conn *Conn) Pass(password string) { conn.Raw(PASS + " " + password) }
func (conn *Conn) Nick(nick string) { conn.Raw(NICK + " " + nick) }
func (conn *Conn) User(ident, name string) {
	conn.Raw(USER + " " + ident + " 12 * :" + name)
}
func (conn *Conn) Join(channel string, key ...string) {
	k := ""
	if len(key) > 0 {
		k = " " + key[0]
	}
	conn.Raw(JOIN + " " + channel + k)
}
func (conn *Conn) Part(channel string, message ...string) {
	msg := strings.Join(message, " ")
	if msg != "" {
		msg = " :" + msg
	}
	conn.Raw(PART + " " + channel + msg)
}
func (conn *Conn) Kick(channel, nick string, message ...string) {
	msg := strings.Join(message, " ")
	if msg != "" {
		msg = " :" + msg
	}
	conn.Raw(KICK + " " + channel + " " + nick + msg)
}
func (conn *Conn) Quit(message ...string) {
	msg := strings.Join(message, " ")
	if msg == "" {
		msg = conn.cfg.QuitMessage
	}
	conn.Raw(QUIT + " :" + msg)
}
func (conn *Conn) Whois(nick string) { conn.Raw(WHOIS + " " + nick) }
func (conn *Conn) Who(nick string) { conn.Raw(WHO + " " + nick) }
func (conn *Conn) Privmsg(t, msg string) {
	prefix := PRIVMSG + " " + t + " :"
	for _, s := range splitMessage(msg, conn.cfg.SplitLen) {
		conn.Raw(prefix + s)
	}
}
func (conn *Conn) Privmsgln(t string, a ...interface{}) {
	msg := fmt.Sprintln(a...)
	msg = msg[:len(msg)-1]
	conn.Privmsg(t, msg)
}
func (conn *Conn) Privmsgf(t, format string, a ...interface{}) {
	msg := fmt.Sprintf(format, a...)
	conn.Privmsg(t, msg)
}
func (conn *Conn) Notice(t, msg string) {
	for _, s := range splitMessage(msg, conn.cfg.SplitLen) {
		conn.Raw(NOTICE + " " + t + " :" + s)
	}
}
func (conn *Conn) Ctcp(t, ctcp string, arg ...string) {
	for _, s := range splitMessage(strings.Join(arg, " "), conn.cfg.SplitLen) {
		if s != "" {
			s = " " + s
		}
		conn.Raw(PRIVMSG + " " + t + " :\001" + strings.ToUpper(ctcp) + s + "\001")
	}
}
func (conn *Conn) CtcpReply(t, ctcp string, arg ...string) {
	for _, s := range splitMessage(strings.Join(arg, " "), conn.cfg.SplitLen) {
		if s != "" {
			s = " " + s
		}
		conn.Raw(NOTICE + " " + t + " :\001" + strings.ToUpper(ctcp) + s + "\001")
	}
}
func (conn *Conn) Version(t string) { conn.Ctcp(t, VERSION) }
func (conn *Conn) Action(t, msg string) { conn.Ctcp(t, ACTION, msg) }
func (conn *Conn) Topic(channel string, topic ...string) {
	t := strings.Join(topic, " ")
	if t != "" {
		t = " :" + t
	}
	conn.Raw(TOPIC + " " + channel + t)
}
func (conn *Conn) Mode(t string, modestring ...string) {
	mode := strings.Join(modestring, " ")
	if mode != "" {
		mode = " " + mode
	}
	conn.Raw(MODE + " " + t + mode)
}
func (conn *Conn) Away(message ...string) {
	msg := strings.Join(message, " ")
	if msg != "" {
		msg = " :" + msg
	}
	conn.Raw(AWAY + msg)
}
func (conn *Conn) Invite(nick, channel string) {
	conn.Raw(INVITE + " " + nick + " " + channel)
}
func (conn *Conn) Oper(user, pass string) { conn.Raw(OPER + " " + user + " " + pass) }
func (conn *Conn) VHost(user, pass string) { conn.Raw(VHOST + " " + user + " " + pass) }
func (conn *Conn) Ping(message string) { conn.Raw(PING + " :" + message) }
func (conn *Conn) Pong(message string) { conn.Raw(PONG + " :" + message) }