Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
ZIRC - The 100% Zsh IRC client :)
- X-seq: zsh-users 10388
- From: Andrew Ruder <andy@xxxxxxxxxxx>
- To: zsh-users@xxxxxxxxxx
- Subject: ZIRC - The 100% Zsh IRC client :)
- Date: Sun, 18 Jun 2006 15:48:43 -0500
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
As you can probably tell by the topic, I had some free time this weekend
and have created quite possibly the *stupidest* ZSH program ever.
ZIRC is an IRC client. It hooks into ZLE's asynchronous select()
support and ZSH's builtin TCP support to do everything. Not a *single*
external, non-zsh command was used in this program. If you're typing
something at the prompt and someone messages you, it'll simply interrupt
your current prompt, print out the message and let you continue with
your typing.
How to use (additional docs at the top of the script):
*) Source the file (. ./zirc)
*) (Optional) Run zsh_aliases, this sets up some aliases to make it a
bit more comfortable to use.
me => zirc_action
msg => zirc_msg
last => zirc_last
connect => zirc_connect
etc...
*) Important commands: command(alias)
zirc_switch(sw): change channel focus
zirc_last(last): change channel focus to last place with a message
zirc_query(query): change focus to username
zirc_msg(msg): message to focused user/channel
zirc_pmsg(pmsg): message to any user/channel
zirc_quit(quit): quit with optional quit message
zirc_nick(nick): change nickname
zirc_connect(connect): connect to IRC server
zirc_part(part): Leave channel
zirc_help(help): List zirc commands
zirc_action(me): Perform action in focused channel/user
*) Screenshot:
(I have my prompt setup to incorporate $ZIRC_CURRENT to show current
focus)
http://dump.aeruder.net/zirc.png
I suppose if you were in some not too busy channels, this thing could be
pretty useful, but really, its mostly designed to just be a joke so you
can tell your friends:
"Yea, well, my shell has an IRC client"
Have fun,
Andrew Ruder
P.S. I'm sure there are still some bugs, but I've just got some other
things I should probably be doing this weekend, 0.2 for bug fixes :)
--
Andrew Ruder <andy@xxxxxxxxxxx>
http://www.aeruder.net
#!/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 <andy@xxxxxxxxxxx>
#
# 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
# <empty line>
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:
# <empty-line>
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:
# <empty-line>
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
# <empty-line>
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 "<CTCP> <$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 *<input>
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 <channel>"
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 <user/channel>"
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 <nick>"
echo "Change nickname to <nick>."
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 <message>"
echo "Will message the current focus <message>."
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 <person> <message>"
echo "Will message the <person> the message <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 <channel>"
echo "Will join the channel <channel>. If <channel> 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 <channel> [<msg>]"
echo "Will leave the channel <channel> with optional part message <msg>."
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 <topic>"
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 <message>"
echo "Send 3rd person action <message>."
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 <server>"
_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
Messages sorted by:
Reverse Date,
Date,
Thread,
Author