- indentation
- user names in bold
- other messages in italic
- own posts are marked in blue as a rudimentary color scheme
package require Tk
set ::server irc.freenode.org
set ::chan #tcl
set ::me $tcl_platform(user)
text .t -height 30 -wrap word -font {Arial 9}
.t tag config bold -font [linsert [.t cget -font] end bold]
.t tag config italic -font [linsert [.t cget -font] end italic]
.t tag config blue -foreground blue
entry .cmd
pack .cmd -side bottom -fill x
pack .t -fill both -expand 1
bind .cmd <Return> post
proc recv {} {
gets $::fd line
# handle PING messages from server
if {[lindex [split $line] 0] eq "PING"} {
send "PONG [info hostname] [lindex [split $line] 1]"
return
}
if {[regexp {:([^!]*)![^ ].* +PRIVMSG ([^ :]+) +:(.*)} $line -> \
nick target msg]} {
set tag ""
if [regexp {\001ACTION(.+)\001} $msg -> msg] {set tag italic}
if [in {azbridge ijchain} $nick] {regexp {<([^>]+)>(.+)} $msg -> nick msg}
.t insert end $nick\t bold $msg\n $tag
} else {.t insert end $line\n italic}
.t yview end
}
proc in {list element} {expr {[lsearch -exact $list $element]>=0}}
proc post {} {
set msg [.cmd get]
if [regexp {^/me (.+)} $msg -> action] {set msg "\001ACTION $action\001"}
foreach line [split $msg \n] {send "PRIVMSG $::chan :$line"}
.cmd delete 0 end
set tag ""
if [regexp {\001ACTION(.+)\001} $msg -> msg] {set tag italic}
.t insert end $::me\t {bold blue} $msg\n [list blue $tag]
.t yview end
}
proc send str {puts $::fd $str; flush $::fd}
set ::fd [socket $::server 6667]
send "NICK $::me"
send "USER $::me 0 * :PicoIRC user"
send "JOIN $::chan"
fileevent $::fd readable recv
bind . <Escape> {exec wish $argv0 &; exit}escargo 8 Mar 2006 - If lines of code is really an important metric to you, the three set commands could be replaced with the foreach idiom to do multiple assignments:
if 0 {
foreach {::server ::chan ::me} {irc.freenode.org #tcl $tcl_platform(user)} break
}That would cut the number of lines by two. - RS: Well, yes, but no... and you'd need a list anyway, since you refer to tcl_platform... My major metrics is not lines of code, but of course I try to remove all redundancies - KISS. But I do prefer scripts with <72 lines, just because in printout they fit on a single page :-)I also noticed the expressions in the if commands were unbraced. Is that right? Is that good style? - RS: I have the rule for myself that an if condition that consists of a single function call (typically returning 0 or 1) can be unbraced - I consider the time needed to parse the strings "0" resp. "1" small enough that I rather spare myself the visual clutter of {[...]}. Matter of taste, of course.vote on reddit at [1] - that forum promped a rewrite of the above in Ruby at http://whytheluckystiff.net/ruby/smircer.rb

Could someone provide this code with verbose comments for those of us that are just learning? There are a few things about this code that I dont understand. For one, I dont see how this snippet deals with IRC's ping/pong behaviour (is it hardcoded into the socket command?). But thats not at all the extent of the confusion, hence the request for verbosity. - RS: Your wish is my command :^) See PicoIRC 0.2 explained.Forgive this post if it breaks the wiki's ettiquite, its my first.
picoIRC 0.3 is a more elaborate version by SS.
MJ - added handling of the PING request.Perhaps its just me, but that ping handler is sending some nastyness into the running of the script
syntax error in expression "[lindex [split $line] 0] eq "PING""
("if" test expression)
while compiling
"if {[lindex [split $line] 0] eq "PING"} {
send "PONG [info hostname] [lindex [split $line] 1]"
return
}"
(compiling body of proc "recv", line 4)
invoked from within
"recv"RS: I suppose it's the "eq" operator. You seem to be running an old Tcl from before 8.4 (which came out 2002...) - just replace eq with == for a quick fix.Category Application - Category Internet

