#!/bin/zsh # vim:noet fdm=marker sw=4 ts=4 ZIRC_VERSION="0.1" # ZIRC - A 100% ZSH IRC client # # Copyright (C) 2006 by Andrew Ruder # # This IRC client is pretty ridiculous, I made it entirely as a joke, but it # actually works fairly decently for as little work has been put into it. # And of course, afaik, there are *no* external commands used in the making # of this program. No grep, no sed, nothing... pretty cool :) # # Guide to using it: # Step 1) Source this file. # . ./zirc or whatever # You can even put this into your .zshrc, it won't hurt anything # besides the creation of several _zirc_*/zirc_* functions. # Step 2) (Optional) Run zsh_aliases # This sets up several aliases to make it easier to use. Basically # it strips the zirc_ front end off of everything. If you want to # see the alias list, type echo $functions[zsh_aliases] # Step 3) Run zirc_connect # It'll explain the syntax and the fairly standardized environment # variables controlling its behavior. # Step 4) Use zirc_msg to message, zirc_pmsg to private message. # zirc_switch can change to another channel. (zirc_switch somechan) # or # zirc_query can change to anything # Step 5) zirc_last is very handy as it switches to the channel/user that # last said something to you. # # Prompt integration: a few environment variables can help you on your way. # $ZIRC_CURRENT = current focus # $ZIRC_NICK = current nickname # $ZIRC_SERVER = connected server # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. [[ -z "$modules[zsh/net/tcp]" ]] && zmodload zsh/net/tcp [[ -z "$modules[zsh/zselect]" ]] && zmodload zsh/zselect ZIRC_PARAMS=( ZIRC_NICK ZIRC_USER ZIRC_NAME ZIRC_PORT ZIRC_HOST ) if ! [[ -z "$ZIRC_FD" ]] && ! [[ -z "$functions[zirc_disconnect]" ]] ; then zirc_disconnect fi ZIRC_VARS=( ZIRC_LAST ZIRC_CHANNELS ZIRC_CURRENT ZIRC_LOWERCASER ZIRC_FD ZIRC_SERVER "${ZIRC_PARAMS[@]}" ) ZIRC_UNSETSTRING="unset ${ZIRC_VARS[*]}" eval "$ZIRC_UNSETSTRING" typeset -g "$ZIRC_VARS[@]" typeset -A ZIRC_PARAM_DEFS ZIRC_PARAM_DEFS[ZIRC_NICK]="Nickname:\$IRCNICK:$USERNAME" ZIRC_PARAM_DEFS[ZIRC_USER]="Username:\$IRCUSER:$USERNAME" ZIRC_PARAM_DEFS[ZIRC_PORT]="Port:\$IRCPORT:6667" ZIRC_PARAM_DEFS[ZIRC_NAME]="Real name:\$IRCNAME:John Doe" ZIRC_PARAM_DEFS[ZIRC_HOST]="Host name:\$IRCHOST:localhost" # zirc_connect parameter handling {{{ # Print out help for the environment variables using the # ZIRC_PARAM_DEFS and ZIRC_PARAMS variables as a reference function _zirc_param_help { local a b echo -e "Environment variables:" for a in "${ZIRC_PARAMS[@]}"; do b=( ${(s/:/)${ZIRC_PARAM_DEFS[$a]}} ) echo -e "\t${b[2]} - ${b[1]} (default ${b[3]})" done } # Fills in the variables in ZIRC_PARAMS using the correct # fallback values specified in ZIRC_PARAM_DEFS function _zirc_param_populate { local a b for a in "$ZIRC_PARAMS[@]"; do b=( ${(s/:/)${ZIRC_PARAM_DEFS[$a]}} ) if [ -z "${(e)b[2]}" ]; then eval "${a}=\"\${b[3]}\"" else eval "${a}=\"\${(e)b[2]}\"" fi done } # }}} # Lowercasing/string comparison code {{{ # Lowercasing according to rfc1459 strictly function _zirc_lowercase_strict_rfc1459 { local msg="${(L)1}" msg=${msg//\[/\{} msg=${msg//]/\}} msg=${msg//\\/\|} echo "${msg}" } # Lowercasing according to rfc1459 function _zirc_lowercase_rfc1459 { local msg="$(_zirc_lowercase_strict_rfc1459 "$1")" msg=${msg//\~/^} echo "${msg}" } # Lowercasing using standard ascii rules function _zirc_lowercase_ascii { echo "${(L)1}" } # Lowercasing according to the current server's specs function _zirc_lowercase { "$ZIRC_LOWERCASER" "$1" } # Case-insensitive compare according to the case-mapping= spec for the server function _zirc_compare { [[ "$("$ZIRC_LOWERCASER" "$1")" == "$("$ZIRC_LOWERCASER" "$2")" ]] } # Determine if a prefix/word is referring to you function _zirc_isme { _zirc_compare "$ZIRC_NICK" "$(_zirc_prefix_nick "$1")" } # }}} # data from server parsing {{{ # Parse a line like # :blah!host blah3 blah4 :Message with lots of words # and output # blah!host # blah3 # blah4 # Message with lots of words function _zirc_parse_server_line { local readval args args=() readval=( "${(f)$(_zirc_parse_server_prefix "$1")}" ) args+=( "${readval[1]}" ) while ! [[ -z "${readval[2]}" ]] ; do readval=( "${(f)$(_zirc_parse_server_word "${readval[2]}")}" ) #" Bug in vim highlighting if ! [[ -z "${readval[1]}" ]]; then args+=( "${readval[1]}" ) fi done echo "${(F)args}" } # Parse a line like # :blah!host blah3 blah4 # and print out # blah!host # blah3 blah4 function _zirc_parse_server_prefix { local line prefix local EXTENDED_GLOB ; EXTENDED_GLOB=1 line="${1## #}" if [[ "${line[1]}" != ":" ]]; then prefix="" else prefix="${line%% *}" if [[ "$prefix" == "$line" ]]; then line="" else line="${line#* }" fi fi echo "${prefix#:}" echo "$line" } # Parse out a single word from a line, so # blah3 blah4 :Message # prints out: # blah3 # blah4 :Message # again: # blah4 # :Message # again # Message # function _zirc_parse_server_word { local line word local EXTENDED_GLOB ; EXTENDED_GLOB=1 line="${1## #}" if [[ "${line[1]}" != ":" ]]; then word="${line%% *}" if [[ "$word" == "$line" ]]; then line="" else line="${line#* }" fi else word="${line#:}" line="" fi echo "$word" echo "$line" } # Split a prefix and get nick (nick!host) # Input: nick!host or nick # Output: # function _zirc_prefix_nick { local a a=( "${(f)$(_zirc_split_prefix "$1")}" ) echo "${a[1]}" } # Split a prefix and get host (nick!host) # Input: nick!host # Output: # host # Input: nick # Output: # function _zirc_prefix_host { local a a=( "${(f)$(_zirc_split_prefix "$1")}" ) echo "${a[2]}" } # Split a prefix # Input: nick!host # Output: # nick # host # Input: nick # Output: # nick # function _zirc_split_prefix { local a a=( ${(s:!:)1} ) [[ ${#a} == "1" ]] && a+=( '' ) echo "${(F)a}" } # }}} # CTCP handling {{{ # Print out the generic ctcp message # Args: prefix command where ctcp msg function _zirc_generic_ctcp { local pref="$1" comm="$2" local where="$3" ctcp="$4" local msg="$5" local who="$(_zirc_prefix_nick "$pref")" _zirc_echo -n " <$who" _zirc_isme "$where" || _zirc_echo -n ":$where" _zirc_echo "> $ctcp $msg" } # Write out a CTCP request # Args: prefix command where ctcp msg function _zirc_ctcp_request_write { local msg if ! [[ -z "$2" ]] && ! [[ -z "$3" ]]; then msg="$2 $3" else msg="$2" fi _zirc_write "`printf "PRIVMSG %s :\001%s\001" "$1" "$msg"`" } # Write out a CTCP reply # Args: where ctcp message function _zirc_ctcp_reply_write { local msg if ! [[ -z "$2" ]] && ! [[ -z "$3" ]]; then msg="$2 $3" else msg="$2" fi _zirc_write "`printf "NOTICE %s :\001%s\001" "$1" "$msg"`" } # Handle a VERSION request function _zirc_ctcp_request_VERSION { _zirc_generic_ctcp "$@" local pref="$1" local who="$(_zirc_prefix_nick "$pref")" _zirc_ctcp_reply_write "$who" "VERSION" "ZIRC $ZIRC_VERSION - 100% zsh!!" } # Handle a PING request function _zirc_ctcp_request_PING { local pref="$1" msg="$5" local who="$(_zirc_prefix_nick "$pref")" _zirc_echo "Received a CTCP PING from $who" _zirc_ctcp_reply_write "$who" "PING" "$5" } # Handle an ACTION function _zirc_ctcp_reply_ACTION { local pref="$1" where="$3" msg="$5" local who="$(_zirc_prefix_nick "$pref")" if ( _zirc_isme "$where" ); then _zirc_compare "$ZIRC_CURRENT" "$who" || ZIRC_LAST="$who" _zirc_echo "*** * $who $msg" else _zirc_echo -n "* $who" _zirc_compare "$ZIRC_CURRENT" "$where" || { ZIRC_LAST="$where" _zirc_echo -n ":$where" } _zirc_echo " $msg" fi } # Handle ACTION requests just like replies function _zirc_ctcp_request_ACTION { _zirc_ctcp_reply_ACTION "$@" } # Handle all other CTCP requests function _zirc_ctcp_request_other { _zirc_generic_ctcp "$@" } # Handle all other CTCP replies function _zirc_ctcp_reply_other { _zirc_generic_ctcp "$@" } # Parse the CTCP stuff and call the appropriate CTCP function above # args: pref command where ctcp+message function _zirc_command_CTCP { local pref="$1" comm="$2" local who="$(_zirc_prefix_nick "$pref")" shift 2 local where="$1" msg="$2" local ctcp func args ctype if [[ "$((#msg))" == "1" ]]; then msg="${msg#?}" fi if [[ "$((##${msg[-1]}))" == "1" ]]; then msg="${msg%?}" fi ctcp="${(U)msg%% *}" msg="${msg#* }" if [[ "$msg" == "$ctcp" ]]; then msg="" fi ctype="request" [[ "$comm" == "NOTICE" ]] && ctype="reply" func="_zirc_ctcp_${ctype}_${ctcp}" if [[ -z "${functions[${func}]}" ]]; then func="_zirc_ctcp_${ctype}_other" fi args=( "$pref" "$comm" "$where" "$ctcp" "$msg" ) "${func}" "$args[@]" } # }}} # Server command handling {{{ # An echo that should be used by anything automatically # called (commands). It invalidates the current prompt line first. function _zirc_echo { zle -I echo "$@" } # Handle private messages function _zirc_command_PRIVMSG { local pref="$1" comm="$2" shift 2 local who="$(_zirc_prefix_nick "$pref")" local where="$1" msg="$2" if [[ "$((#msg))" == "1" ]]; then _zirc_command_CTCP "$pref" "$comm" "$where" "$msg" return 0 fi if ( _zirc_isme "$where" ); then _zirc_compare "$ZIRC_CURRENT" "$who" || ZIRC_LAST="$who" _zirc_echo "*** <$who> $msg" else _zirc_echo -n "<$who" _zirc_compare "$where" "$ZIRC_CURRENT" || { _zirc_echo -n ":$where" ZIRC_LAST="$where" } _zirc_echo "> $msg" fi } # Handle nickname changes function _zirc_command_NICK { local pref="$1" newnick="$3" local who="$(_zirc_prefix_nick "$pref")" if [[ "$who" == "$ZIRC_CURRENT" ]]; then ZIRC_CURRENT="${newnick}" fi _zirc_isme "$pref" && ZIRC_NICK="$newnick" _zirc_echo "$who is now known as $newnick" } # Handle channel joins function _zirc_command_JOIN { local pref="$1" comm="$2" shift 2 local who="$(_zirc_prefix_nick "$pref")" local at="$(_zirc_prefix_host "$pref")" local where="$1" _zirc_echo "$who ($at) has joined $where" _zirc_isme "$pref" && { ZIRC_LAST="$ZIRC_CURRENT" ZIRC_CURRENT="$where" ZIRC_CHANNELS+=("$where") } } # Handle channel parts function _zirc_command_PART { local pref="$1" comm="$2" where="$3" msg="$4" local who="$(_zirc_prefix_nick "$pref")" _zirc_echo "$who has left $where ($msg)" _zirc_isme "$pref" && { [[ ZIRC_CURRENT == "$where" ]] && ZIRC_CURRENT="$ZIRC_LAST" ZIRC_CHANNELS[(r)$where]=() } } # Handle people quitting function _zirc_command_QUIT { local pref="$1" comm="$2" msg="$3" local who="$(_zirc_prefix_nick "$pref")" _zirc_echo "$who has quit IRC ($msg)" } # Handle topic changes function _zirc_command_TOPIC { local pref="$1" comm="$2" where="$3" msg="$4" local who="$(_zirc_prefix_nick "$pref")" _zirc_echo "$who has changed the topic in $where to '$msg'" } # Handle mode changes function _zirc_command_MODE { local pref="$1" comm="$2" object="$3" mode="$4" local who="$(_zirc_prefix_nick "$pref")" local rest rest=( "${@[4,-1]}" ) rest=( " "${^rest} ) rest=${(j::)rest} _zirc_echo "$who sets mode $mode ${object}${rest}" } # Handle invites function _zirc_command_INVITE { local pref="$1" comm="$2" where="$4" local who="$(_zirc_prefix_nick "$pref")" _zirc_echo "$who has invited you to $where" } # Handle kicks function _zirc_command_KICK { local pref="$1" comm="$2" where="$3" user="$4" msg="$5" local who="$(_zirc_prefix_nick "$pref")" _zirc_echo "$user was kicked from $where by $who ($msg)" } # Handle pong messages (shouldn't get these generally, but just in case) function _zirc_command_PONG { } # Handle notices, although we just forward this onto the privmsg code function _zirc_command_NOTICE { _zirc_command_PRIVMSG "$@" return } # Handle wallops function _zirc_command_WALLOPS { local pref="$1" comm="$2" msg="$3" local who="$(_zirc_prefix_nick "$pref")" _zirc_echo "Wallops from $who: $msg" } # Handle IRC Errors function _zirc_command_ERROR { local pref="$1" comm="$2" shift 2 _zirc_echo "ERROR: ${(j: :)@}" } # Handle server pings function _zirc_command_PING { local pref="$1" comm="$2" shift 2 _zirc_write "PONG :$1" } # RPL_WELCOME handler... this will (among other things) # inform us of our true nickname function _zirc_command_numeric_001 { ZIRC_NICK="$3" } # RPL_ISUPPORT this tells us how to handle casemapping function _zirc_command_numeric_005 { case "$4" in *casemapping=rfc1459*) ZIRC_LOWERCASER="_zirc_lowercase_rfc1459" ;; *casemapping=strict-rfc1459*) ZIRC_LOWERCASER="_zirc_lowercase_strict_rfc1459" ;; *casemapping=ascii*) ZIRC_LOWERCASER="_zirc_lowercase_ascii" ;; esac } # Handle numeric commands function _zirc_command_numeric { local pref="$1" comm="$2" _zirc_echo "-- ${(j: :)@[4,-1]}" if ! [[ -z "$functions[_zirc_command_numeric_${comm}]" ]]; then _zirc_command_numeric_"$comm" "$@" fi } # catchall for unhandled commands function _zirc_command_other { local EXTENDED_GLOB=1 local pref="$1" comm="$2" shift 2 if [[ "$comm" == [0-9]## ]]; then _zirc_command_numeric "$pref" "$comm" "$@" return 0 fi } # }}} # ZLE hooks {{{ # Parse a single line of incoming data function _zirc_handle_incoming_data_piece { local line comm func output line="$1" line=( "${(f)$(_zirc_parse_server_line "$line")}" ) comm="${(U)line[2]}" func="_zirc_command_${comm}" if [[ -z "${functions[${func}]}" ]]; then func="_zirc_command_other" fi "$func" "$line[@]" } # The ZLE informs this when there is data. Grab the data, and then # grab any additional data available (using zselect) and passing all # of this back off to the _zirc_handle_incoming_data_piece function function _zirc_handle_incoming_data { local fds line if [[ "$1" != "$ZIRC_FD" ]]; then zle -I echo "ZIRC: Handling some other file handle???" return 1 fi while true; do if ! read -r line <&$ZIRC_FD; then zle -I zirc_disconnect return 1 fi if [[ "$((##${line[-1]}))" == "13" ]]; then line="${line%?}" fi _zirc_handle_incoming_data_piece "$line" fds=() zselect -r -t 0 -a fds $ZIRC_FD if [[ "${#fds}" != "2" ]]; then break fi done } # }}} # User commands and utility functions used by them {{{ # Write out a message to the server. It puts on the correct line ending # for the IRC protocol too function _zirc_write { local a if [[ -z "$ZIRC_FD" ]]; then return 1 fi if [[ -z "$1" ]]; then return 0 fi a="$@" printf "%s\r\n" "$a" >&$ZIRC_FD } # Send the initial connection lines to the server function _zirc_send_connect_lines { _zirc_write "NICK $ZIRC_NICK" _zirc_write "USER $ZIRC_USER $ZIRC_HOST $ZIRC_SERVER :$ZIRC_NAME" } # Input: # channel name (or part of a channel name) # Output: # shortest channel that matches * function _zirc_channel_match { local chan="$1" local chans shortest a chan="*${chan}" chans=( "${ZIRC_CHANNELS[@]}" ) chans=( ${(e):-\${(M)chans:#$chan}} ) if [[ "${#chans}" == "0" ]]; then echo "" return 1 fi shortest=" "; shortest="${(l:1000:: :)shortest}" for a in "${chans[@]}"; do (( ${#a} < ${#shortest} )) && shortest="${a}" done echo "${shortest}" return 0 } # Switch focus. This uses _zirc_channel_match so the globbing will make it # easier to switch channels. # # zirc_switch step # # would change to #gnustep if you were correctly connected to that channel function zirc_switch { local chan="$1" local chans shortest a zirc_connected || { echo "Not connected" ; return 1 } if [[ -z "$chan" ]]; then echo "Usage: $0 " echo "Switches current channel focus (Current: '${ZIRC_CURRENT}')" echo "This command is only used for channels, use zirc_query for a more" echo "general solution." return 1 fi chan="$(_zirc_channel_match "$chan")" if [[ -z "$chan" ]]; then echo "Could not find anything for '$1'" echo "Current channels: ${(j:,:)ZIRC_CHANNELS}" return 1 fi ZIRC_LAST="$ZIRC_CURRENT" ZIRC_CURRENT="${chan}" echo "Switched to $ZIRC_CURRENT" return 0 } # Just switch focus to the argument. Don't check against anything else. function zirc_query { local query="$1" zirc_connected || { echo "Not connected" ; return 1 } if [[ -z "$query" ]]; then echo "Usage: $0 " echo "Switches current focus. (Current: '${ZIRC_CURRENT}')" echo "No expansion will be done on the parameter. If you are switching" echo "to a channel, you may try zirc_switch instead as it will expand to" echo "the best match without you having to deal with the escaping." return 1 fi ZIRC_LAST="$ZIRC_CURRENT" ZIRC_CURRENT="${query%% *}" echo "Switched to $ZIRC_CURRENT" } # Switch to the last focused window or wherever there was a message last function zirc_last { local a [[ -z "$ZIRC_LAST" ]] && return 0 a="$ZIRC_CURRENT" ZIRC_CURRENT="${ZIRC_LAST}" ZIRC_LAST="$a" echo "Switched to $ZIRC_CURRENT" } # Quit (with optional quit message) function zirc_quit { local msg="${(j: :)@}" zirc_connected || { echo "Not connected" ; return 1 } [[ -z "$msg" ]] && msg="ZIRC $ZIRC_VERSION - 100% zsh, woot." _zirc_write "QUIT :$msg" } # Print out current focus. Could be used to hook into prompts function zirc_focus { zirc_connected || { echo "Not connected" ; return 1 } echo "$ZIRC_CURRENT" } # Print out zirc_* functions function zirc_help { local commands commands=( "${(k)functions[@]}" ) commands=( ${(M)commands:#zirc_*} ) commands=( ${(o)commands} ) commands=( " "${^commands} ) echo "ZIRC Commands:" echo "${(F)commands}" return 0 } # Change nickname to argument function zirc_nick { local nick="$1" zirc_connected || { echo "Not connected" ; return 1 } if [[ -z "$nick" ]]; then echo "Usage: $0 " echo "Change nickname to ." return 1 fi _zirc_write "NICK ${nick%% *}" } # Message the current focus function zirc_msg { local msg="${(j: :)@}" zirc_connected || { echo "Not connected" ; return 1 } if [[ -z "$msg" ]]; then echo "Usage: $0 " echo "Will message the current focus ." echo "Use zirc_query/zirc_switch to change focus. (Current: '${ZIRC_CURRENT}')" return 1 fi if [[ -z "$ZIRC_CURRENT" ]]; then echo "No current focus. Use zirc_query/zirc_switch to change focus." return 1 fi echo "<$ZIRC_NICK:$ZIRC_CURRENT> ${msg}" _zirc_write "PRIVMSG ${ZIRC_CURRENT} :${msg}" } # Message someone (temporarily changing focus then calling zirc_msg) function zirc_pmsg { local who="$1" shift local msg="${(j: :)@}" local temp_current temp_result zirc_connected || { echo "Not connected" ; return 1 } if [[ -z "$msg" ]] || [[ -z "$who" ]]; then echo "Usage: $0 " echo "Will message the the message ." echo "Also see zirc_msg." return 1 fi temp_current="$ZIRC_CURRENT" ZIRC_CURRENT="$who" zirc_msg "$msg" temp_result="$?" ZIRC_CURRENT="$temp_current" return "$temp_result" } # Join a channel function zirc_join { local chan="$1" zirc_connected || { echo "Not connected" ; return 1 } if [[ -z "$chan" ]]; then echo "Usage: $0 " echo "Will join the channel . If starts with a letter" echo "or a number, it will be prepended with a '#'" return 1 fi [[ "$chan" == [a-zA-Z0-9]* ]] && chan="#${chan}" _zirc_write "JOIN ${chan%% *}" } # Leave a channel (with optional part message) function zirc_part { local chan="$1" unchan="$1" shift local msg="${(j: :)@}" zirc_connected || { echo "Not connected" ; return 1 } if [[ -z "$chan" ]]; then echo "Usage: $0 []" echo "Will leave the channel with optional part message ." echo "This routine will use the same matching method as zirc_switch so" echo "you don't have to type the '#' or any other tricky characters" #'" ft=zsh sucks return 1 fi chan="$(_zirc_channel_match "$chan")" if [[ -z "$chan" ]]; then echo "Could not find anything for '$unchan'" echo "Current channels: ${(j:,:)ZIRC_CHANNELS}" return 1 fi _zirc_write "PART ${chan%% *} :${msg}" } # Change the topic in current focus function zirc_topic { local topic="${(j: :)@}" zirc_connected || { echo "Not connected" ; return 1 } if [[ -z "$topic" ]]; then echo "Usage: $0 " echo "Change the topic in the current channel. Use zirc_switch" echo "to change the channel (Current: '$ZIRC_CURRENT')." return 1 fi _zirc_write "TOPIC ${ZIRC_CURRENT} :${topic}" } # Send a CTCP action to the current focus function zirc_action { local msg="${(j: :)@}" zirc_connected || { echo "Not connected" ; return 1 } if [[ -z "$msg" ]]; then echo "Usage: $0 " echo "Send 3rd person action ." echo "Sends to the current focus (Current: '$ZIRC_CURRENT')." return 1 fi echo "* $ZIRC_NICK:$ZIRC_CURRENT ${msg}" _zirc_write "$(printf "PRIVMSG $ZIRC_CURRENT :\001ACTION ${msg}\001")" } # Print out current topic function zirc_checktopic { zirc_connected || { echo "Not connected" ; return 1 } _zirc_write "TOPIC ${ZIRC_CURRENT}" } # Returns success if currently connected function zirc_connected { ! [[ -z "$ZIRC_FD" ]] } # Connect to a server function zirc_connect { if ! [[ -z "$ZIRC_FD" ]]; then zirc_disconnect zirc_connect return fi if [[ -z "$1" ]]; then echo -e "Usage: $0 " _zirc_param_help return 1 fi ZIRC_SERVER="$1" ZIRC_LOWERCASER="_zirc_lowercase_rfc1459" ZIRC_CURRENT="" ZIRC_CHANNELS=() _zirc_param_populate ztcp "$ZIRC_SERVER" "$ZIRC_PORT" || return 1 ZIRC_FD="$REPLY" zle -F "$ZIRC_FD" _zirc_handle_incoming_data _zirc_send_connect_lines echo "Connected to $ZIRC_SERVER on fd #$ZIRC_FD" return 0 } # Disconnect from a server function zirc_disconnect { if [[ -z "$ZIRC_FD" ]]; then return 0 fi echo "Disconnecting from $ZIRC_SERVER..." zle -F "$ZIRC_FD" ztcp -c "$ZIRC_FD" eval "$ZIRC_UNSETSTRING" return 0 } # Setup aliases function zirc_aliases { echo "Setting up some convenience aliases" alias me='zirc_action' alias nick='zirc_nick' alias msg='zirc_msg' alias pmsg='zirc_pmsg' alias quit='zirc_quit' alias ctopic='zirc_topic' alias topic='zirc_checktopic' alias part='zirc_part' alias last='zirc_last' alias join='zirc_join' alias sw='zirc_switch' alias query='zirc_query' alias connect='zirc_connect' alias help='zirc_help' } # }}}3