├── tmiii.sh ├── UNLICENSE ├── connect.sh ├── notifiii.sh ├── README.mkdn └── iii.sh /tmiii.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # Ivan c00kiemon5ter V Kanakarakis (http://c00kiemon5ter.github.com) 3 | # for noncopyright information see UNLICENSE file http://unlicense.org/ . 4 | # 5 | # wrapper around iii.sh 6 | # spawns iii.sh in a tmux session named IRC with the channel as title 7 | # accepts all env vars iii.sh accepts plus 't' which sets the terminal 8 | 9 | ## collect options from env - all opts to iii.sh should be set here 10 | opts="TERM="${t:-rxvt-unicode}" m="$m" h="$h" p="$p" n="$n" l="$l" i="$i" s="$s" c="$c"" 11 | 12 | ## spawn a new tmux window named in a tmux session named IRC 13 | if ! tmux list-sessions | awk -v r=1 '$1 == "IRC:" { exit r=0 } END { exit r }' 14 | then tmux new-session -s IRC -n "${c:-$s}" "$opts iii.sh" 15 | elif ! tmux list-windows -t IRC | awk -v r=1 -v m="${c:-$s}" '$2 ~ "^"m"[*!-]*$" { exit r=0 } END { exit r }' 16 | then tmux new-window -t IRC -n "${c:-$s}" -d "$opts iii.sh" 17 | fi 18 | 19 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /connect.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | : "${ircdir:=$HOME/irc}" 4 | : "${nick:=$USER}" 5 | 6 | # server info functions 7 | freenode() { 8 | server='irc.freenode.net' 9 | channels="#foo #bar" 10 | } 11 | 12 | oftc() { 13 | server='irc.oftc.net' 14 | channels="#xyz #abc" 15 | } 16 | 17 | # these match the functions above 18 | networks="freenode oftc" 19 | 20 | # some privacy please, thanks 21 | chmod 700 "$ircdir" 22 | chmod 600 "$ircdir"/*/ident &>/dev/null 23 | 24 | for network in $networks; do 25 | unset server channels port 26 | "$network" # set the appropriate vars 27 | 28 | while true; do 29 | # cleanup 30 | rm -f "$ircdir/$server/in" 31 | 32 | # connect to netwrok -- password is set through the env var synonym to the network name 33 | iim -i "$ircdir" -n "$nick" -k "$network" -s "$server" -p "${port:-6667}" & 34 | pid="$!" 35 | 36 | # wait for the connection 37 | while ! test -p "$ircdir/$server/in"; do sleep .3; done 38 | 39 | # auth to services 40 | if [ -e "$ircdir/$server/ident" ] 41 | then printf "/j nickserv identify %s\n" "$(cat "$ircdir/$server/ident")" > "$ircdir/$server/in" 42 | fi && rm -f "$ircdir/$server/nickserv/out" # clean that up - ident passwd is in there 43 | 44 | # join channels 45 | printf "/j %s\n" $channels > "$ircdir/$server/in" 46 | 47 | # if connection is lost reconnect 48 | wait "$pid" 49 | done & 50 | done 51 | 52 | -------------------------------------------------------------------------------- /notifiii.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # Ivan c00kiemon5ter V Kanakarakis (http://c00kiemon5ter.github.com) 3 | # for noncopyright information see UNLICENSE file http://unlicense.org/ . 4 | # 5 | # monitor the given irc directory tree for changes - ignores server messages 6 | # and spawns tmiii.sh or a new urxvt terminal with the chanel that had activity 7 | 8 | i="${1:-$HOME/irc}" 9 | GREP_OPTIONS="" 10 | 11 | trap 'kill -TERM -0' EXIT 12 | 13 | inotifywait -m --exclude "/in$" --format "%w %f" -e modify -r "$i" | \ 14 | while read -r p f; do 15 | # ignore notifications files other than 'out' 16 | [ "$f" != "out" ] && continue 17 | 18 | # ignore messages from server 19 | nickname="$(awk '{ n=$3 } END { print n }' "$p$f")" 20 | nickname="${nickname#<}" 21 | nickname="${nickname%>}" 22 | case "$nickname" in -!-) continue ;; esac 23 | 24 | # break path down # p=/ircdir/server/channel/ 25 | p="${p#$i}" # p=/server/channel/ 26 | p="${p%/*}" # p=/server/channel 27 | c="${p##*/}" # c=channel 28 | p="${p%/*}" # p=/server 29 | s="${p##*/}" # s=server 30 | # if server is empty then action is on the server view 31 | [ -z "$s" ] && s="$c" c="" 32 | 33 | opts="h=50 i="$i" s="$s" c="$c"" 34 | 35 | ## spawn a new tmux window named in a tmux session named IRC 36 | env $opts tmiii.sh 37 | 38 | # ## spawn a new urxvt terminal with IRC- class name 39 | # if ! xwininfo -root -children | sed -n 's,^ \+\(0x[^ ]\+\).*("\([^"]*\)" "\([^"]*\)").*\+,"\1 \2 \3",p' | grep "${c:-$s} URxvt" 40 | # then env $opts urxvtc -name "IRC-${c:-$s}" -e iii.sh 41 | # fi 42 | done 43 | 44 | -------------------------------------------------------------------------------- /README.mkdn: -------------------------------------------------------------------------------- 1 | 2 | iii 3 | --- 4 | 5 | `iii` is a frontend to `ii`/`iim` so that one can easily view and send messages. 6 | it outputs text, formatted, and colored, and allows for some configuration. 7 | options are passed as enviromental variables. 8 | 9 | u: the user's nickname 10 | i: the root directory [default: $HOME/irc] 11 | n: the network in which the channel resides [default: irc.oftc.net] 12 | c: the channel to interact with [default: none - the network view] 13 | m: max length for nicks [default: 12] 14 | h: the number of lines to include from history [default: 20] 15 | s: the separator between the nick and the message 16 | r: randomization of nick colors 17 | l: the highlight color when nick is mentioned 18 | 19 | typical usage would be: 20 | 21 | ``` sh 22 | c=#suckless iii.sh 23 | h=50 n=irc.freenode.net c=#musl iii.sh 24 | ``` 25 | 26 | to quit `iii` just send `:q`. 27 | to mark the current spot on the conversation send `:m`. 28 | to quit and mark send `:x`. 29 | 30 | some common commands are supported, 31 | like `/op` `/deop` `/ban` `/unban` `/names` `/wi` 32 | 33 | tmiii 34 | ----- 35 | 36 | `tmiii` is a wrapper to `iii` to spawn `iii` instances inside a `tmux` session named *IRC*. 37 | each `iii` instance inside `tmux` is on each own window, named by the channel it shows. 38 | `tmiii` acceps the same env vars as `iii` plus `t` to set the TERM variable, used by `tmux`. 39 | 40 | ``` sh 41 | l=false h=50 n=irc.freenode.net c=#cat-v tmiii.sh 42 | ``` 43 | 44 | notifiii 45 | -------- 46 | 47 | `notifiii` monitors a hierarchy of files and automatically spawns a terminal running `iii` with the channel that got activity. 48 | `notifiii` by default ignores joins, parts, quits and any message from the network (user `-!-`). 49 | `notifiii` accepts the irc root directory - by default `$HOME/irc` - to monitor as an argument. 50 | 51 | ``` sh 52 | notifiii.sh /tmp/irc 53 | ``` 54 | 55 | connect 56 | ------- 57 | 58 | `connect` is a script to automatically connect `ii`/`iim` to the specified networks and channels. 59 | in addition, it knows when the connection was dropped and automatically tries to reconnect. 60 | moreover, given a file named `ident`, containing the identification passphrase of the user, 61 | it sends an identify command to the _nickserv_, to automatically identify the connected user. 62 | the `ident` file should be under `/path/to/irc/dir/network/` 63 | 64 | as above `connect` accepts two arguments in the form of env vars, 65 | `nick` which sets the user's nickname, else it will use `$USER`, 66 | and `ircdir` which specifies the base irc directory. 67 | 68 | ``` sh 69 | $ freenode=foo oftc=bar connect.sh 70 | $ ^ notice the extra space here 71 | $ this serves as to ignore the command from being saved in the shell history 72 | $ one should also close the terminal or clear the scrollback buffer 73 | $ so that the command cannot be seen on scroll up 74 | ``` 75 | 76 | edit this script to add the networks you'd like to autoconnect as a function, 77 | which sets the server name, the channels on that server to autoconnect as a 78 | list of strings separated by a space, and the port to use for the connection. 79 | add your network to the `networks` list, and you're set. 80 | 81 | dependencies 82 | ------------ 83 | 84 | * [inotify-tools][in] 85 | * [rlwrap][rl] - readline wrapper 86 | 87 | [in]: https://github.com/rvoicilas/inotify-tools/wiki 88 | [rl]: http://utopia.knoware.nl/~hlub/rlwrap/ 89 | 90 | bugs 91 | ---- 92 | 93 | * inotify is not portable - linux only interface. 94 | 95 | related 96 | ------- 97 | 98 | * [iim](https://github.com/c00kiemon5ter/iim) 99 | * [ii](http://tools.suckless.org/ii/) 100 | 101 | * [nii](https://bitbucket.org/bobertlo/nii) 102 | * [pcw](https://bitbucket.org/emg/pcw) 103 | * [srw](https://bitbucket.org/emg/srw) 104 | * [im-scripts](https://github.com/gravicappa/im-scripts) 105 | * [niii](https://github.com/c00kiemon5ter/niii) 106 | 107 | non-copyright 108 | ------------- 109 | 110 | code and text for `iii` `tmiii` and `notifiii` are unlicensed. 111 | see UNLICENSE file and [unlicense.org](http://unlicense.org/) for more information. 112 | 113 | original hacks by [Ivan c00kiemon5ter V Kanakarakis](http://c00kiemon5ter.github.com). 114 | if you have cookies, share :] 115 | 116 | -------------------------------------------------------------------------------- /iii.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # Ivan c00kiemon5ter V Kanakarakis (http://c00kiemon5ter.github.com) 3 | # for noncopyright information see UNLICENSE file http://unlicense.org/ . 4 | # 5 | # frontend to ii/iim for a single channel 6 | # follows the tail of the out file 7 | # and redirects input to the in file 8 | 9 | : "${n:=$USER}" # the user's nickname 10 | : "${i:=$HOME/irc}" # root irc dir 11 | : "${s:=irc.freenode.net}" # server 12 | : "${c:=""}" # channel 13 | : "${m:=12}" # max nick lenght 14 | : "${w:=120}" # max characters per mesg - fold after limit 15 | : "${h:=20}" # lines from history 16 | : "${p:=1}" # prefity - colors and special patterns 17 | 18 | [ "$1" != '-r' ] && exec rlwrap -a -r -S "${c:-$s}> " -pGREEN "$0" -r 19 | 20 | infile="$i/$s/$c/in" 21 | outfile="$i/$s/$c/out" 22 | sepr='|' 23 | 24 | # colors 25 | reset="$(tput sgr0)" 26 | dark="$(tput setaf 8)" 27 | highlight="$(tput setaf 3)" 28 | 29 | # markup 30 | sb="$(tput bold; tput setaf 9)" 31 | eb="$(tput sgr0; tput sgr0)" 32 | su="$(tput smul; tput setaf 11)" 33 | eu="$(tput rmul; tput sgr0)" 34 | si="$(tput sitm; tput setaf 13)" 35 | ei="$(tput ritm; tput sgr0)" 36 | 37 | [ -p "$infile" ] || exit 1 38 | [ -e "$outfile" ] || { touch "$outfile" || exit 1; } 39 | 40 | tail -f -n "$h" "$outfile" | while IFS= read -r line 41 | do 42 | unset date time nick mesg ctcp 43 | 44 | date="${line%% *}" line="${line#* }" 45 | time="${line%% *}" line="${line#* }" 46 | nick="${line%% *}" line="${line#* }" 47 | 48 | # strip '' to 'nick' 49 | nick="${nick#<}" nick="${nick%>}" 50 | 51 | # do not notify of server messages 52 | case "$nick" in -!-) ;; *) tput bel ;; esac 53 | 54 | # prettify 55 | if [ "$p" -ne 0 ] 56 | then 57 | unset clrdate clrnick clrsepr clrmesg tmpnick 58 | 59 | clrdate="$dark" 60 | case "$line" in *"$n"*) clrdate="$highlight" ;; esac 61 | 62 | tmpnick="${nick%[_12]}" 63 | clrnick="$(printf '(%d ^ %d + %d + %d)' "${#tmpnick}" "'${tmpnick}" "'${tmpnick#?}" "'${tmpnick#??}")" 64 | 65 | # avoid black(1,8), dark blue(4), bright yellow(11) and white(7, 15) 66 | clrnick="$(($clrnick % 10 + 1))" 67 | case "$clrnick" in 4) clrnick=12 ;; 7) clrnick=13 ;; 8) clrnick=14 ;; esac 68 | 69 | clrnick="$(tput setaf "$clrnick")" 70 | clrsepr="$dark" 71 | clrmesg="$reset" 72 | 73 | # dark color for special nicks 74 | case "$nick" in -!-) clrnick="$dark" clrmesg="$dark";; esac 75 | fi 76 | 77 | # handle CTCP messages 78 | if [ "${line#}" != "${line}" ] 79 | then 80 | line="${line#}" 81 | line="${line%}" 82 | ctcp="${line%% *}" 83 | line="${line#* }" 84 | 85 | if [ "$ctcp" != 'ACTION' ] 86 | then line="${clrnick}[CTCP:${ctcp}]${clrmesg} ${line}" 87 | else line="${clrnick}${nick}${clrmesg} ${line}" nick="*" 88 | fi 89 | fi 90 | 91 | # fold lines breaking on spaces if message is greater than 'w' chars or does not fit 92 | mw="$(($(tput cols) - ${#date} - ${#time} - $m - 5))" 93 | [ "$mw" -gt "$w" ] && mw="$w" 94 | printf '%s\n' "$line" | fold -s -w "$mw" | while IFS= read -r mesg; \ 95 | do 96 | [ "$p" -gt 1 ] && mesg="$(echo "$mesg" | sed \ 97 | -e "s,\(^\|[[:space:]][[:punct:]]*\)\([_][[:alnum:][:punct:]]\+[_]\)\([[:punct:][:space:]]\|$\),\1${su}\2${eu}\3,g" \ 98 | -e "s,\(^\|[[:space:]][[:punct:]]*\)\([_][[:alnum:][:punct:]]\+[_]\)\([[:punct:][:space:]]\|$\),\1${su}\2${eu}\3,g" \ 99 | -e "s,\(^\|[[:space:]][[:punct:]]*\)\([/][[:alnum:][:punct:]]\+[/]\)\([[:punct:][:space:]]\|$\),\1${si}\2${ei}\3,g" \ 100 | -e "s,\(^\|[[:space:]][[:punct:]]*\)\([/][[:alnum:][:punct:]]\+[/]\)\([[:punct:][:space:]]\|$\),\1${si}\2${ei}\3,g" \ 101 | -e "s,\(^\|[[:space:]][[:punct:]]*\)\([*][[:alnum:][:punct:]]\+[*]\)\([[:punct:][:space:]]\|$\),\1${sb}\2${eb}\3,g" \ 102 | -e "s,\(^\|[[:space:]][[:punct:]]*\)\([*][[:alnum:][:punct:]]\+[*]\)\([[:punct:][:space:]]\|$\),\1${sb}\2${eb}\3,g")" 103 | 104 | printf '\r%s%s %s %s%*.*s %s%s %s%s%s\n' \ 105 | "${clrdate}" "${date}" "${time}" \ 106 | "${clrnick}" "${m}" "${m}" "${nick}" \ 107 | "${clrsepr}" "${sepr}" \ 108 | "${clrmesg}" "${mesg}" "${reset}" 109 | done 110 | done & 111 | 112 | trap "stty '$(stty -g)'; kill -TERM 0" EXIT 113 | stty -echonl -echo 114 | 115 | bar="--------------------------------------------------------------------------------" 116 | mark() { printf '%s -!- %.*s\n' "$(date +"%F %R")" "$w" "${bar}${bar}" >>"$outfile"; } 117 | 118 | while IFS= read -r input; do 119 | case "$input" in 120 | '') 121 | continue 122 | ;; 123 | :m) 124 | mark 125 | continue 126 | ;; 127 | :x) 128 | mark 129 | break 130 | ;; 131 | :q) 132 | break 133 | ;; 134 | /wi" "*) 135 | input="/j nickserv info ${input#/wi}" 136 | ;; 137 | /me" "*) 138 | input="ACTION${input#/me}" 139 | ;; 140 | /names) 141 | input="/names $c" 142 | ;; 143 | /op" "*) 144 | input="/j chanserv op $c ${input##* }" 145 | ;; 146 | /deop" "*) 147 | input="/j chanserv deop $c ${input##* }" 148 | ;; 149 | /bans) 150 | input="/j chanserv akick $c LIST" 151 | ;; 152 | /ban" "*) 153 | input="/j chanserv akick $c ADD ${input##* } -- goodbye" 154 | ;; 155 | /unban" "*) 156 | input="/j chanserv akick $c DEL ${input##* }" 157 | ;; 158 | /t) 159 | input="/topic $c" 160 | ;; 161 | esac 162 | [ -n "$input" ] && printf '%s\n' "$input" 163 | done >"$infile" 164 | 165 | --------------------------------------------------------------------------------