vipirc 0.3.1 - terminal IRC client

An application of ThatIAm.vip (www.thatiam.vip).
Designed by remfan1994.
Source available under the included IALA (Insha-Allah License Agreement).
The full license is in LICENSE.md. Website: https://www.thatiam.vip

QUICK START

    vipirc -h
    vipirc -v
    vipirc --test-mode

These show command help, show the version, and open interactive offline
simulation. For a real connection:

    vipirc --server irc.ircnow.org --channel '#ircnow' --nick tutankh-aten

Quote channel arguments in a shell: an unquoted # can start a shell comment.
The default transport is certificate-verified TLS on port 6697. A server
must actually offer TLS on the selected port. Plain IRC requires --plain.

Every interactive launch begins with:

    Not vegetarian?  www.bloodguiltcurse.net will change your mind

Press an ordinary printable key, Enter, Tab, or a navigation key to dismiss
the welcome. Terminal signal keys keep their meaning: Ctrl-C exits with
status 130; Ctrl-Z suspends, and fg resumes the same welcome screen.
SIGQUIT exits with status 131 after terminal cleanup. Custom terminal
signal characters are respected; other control bytes do not dismiss it.
In normal connection mode,
missing server and nickname values are requested in the terminal. The
nickname prompt offers your Unix login name as its default; Enter accepts
it. A value typed at that prompt
replaces the default. The server can reject a nickname under its own rules.

If no channel is selected, the initial conversation is the server view,
including the server's welcome messages and message of the day (MOTD).
Configured channels are joined after successful registration and required
authentication. The server can refuse a channel join. Servers on the main
toolbar opens a list for adding and switching between up to eight server
sessions in this terminal. Each has its own channels, queries, and settings.

The client starts in Navigation with the original keymap. Press Tab to
enter Input, then type text and press Enter to send it to the current
channel or private conversation. Server and mentions views have no implicit
chat recipient. Use /join or /msg
to choose a conversation.

For a literal message beginning with /, type // followed by the rest of the
message. Bracketed pasted text is always treated as text, even when it
begins with /. Pasting does not send the text automatically.

GETTING HELP

    vipirc -h              command-line summary; --help is equivalent
    vipirc -v              program version; --version is equivalent
    vipirc --manual        this complete manual on standard output
    man vipirc             installed Unix manual page
    /help or /manual       manual inside the running client

/help, /manual, /view help, Actions > Help, and original-keymap Navigation h
all open the same secondary Help / Manual screen. It works while disconnected
and has no chat input field. It remembers the previous main view and preserves
that view's draft. A typed command that opens the manual is consumed normally.

Up/Down scrolls a line, Page Up/Page Down scrolls a page, and Home/End goes
to the beginning/end. The Vim-style preset also provides j/k and g/G.
Escape, Enter, q, or the focused Back control returns directly to the
previous main view in Navigation. Vim h/l also returns. The main toolbar
focus and previous draft are preserved. Tab stays in the reader and reports:

    Input is on the chat screen. Press Esc to return.

Return first, then use Tab to focus Input. Pasted text is ignored in the
manual. Next/previous view cycling, including n/p and /next or /prev,
skips Help. On the main screen, Escape opens Settings as usual.

COMMAND-LINE OPTIONS

    -s, --server HOST
        Select a server hostname or numeric IPv4/IPv6 address. Supply a host,
        not an irc:// URL. Use --port for the port.
    -p, --port PORT
        Select a TCP port in the range 1 through 65535.
    -c, --channel CHANNEL
        Auto-join a channel after registration. A comma-separated list or
        repeated --channel options selects several channels.
    -n, --nick NICK
        Select a nickname. Without a selected nickname, the terminal prompt
        offers your Unix login name.
    -C, --config FILE
        Select the primary server configuration and its adjacent server
        catalog. Connection command-line overrides affect this primary
        profile only. The default is
        $XDG_CONFIG_HOME/vipirc/config.ini when XDG_CONFIG_HOME is set, or
        $HOME/.config/vipirc/config.ini otherwise. XDG_CONFIG_HOME must be
        absolute. An explicitly selected file must exist except when it is
        being created with --init-config.
    --tls
        Use verified TLS. The usual default TLS port is 6697.
    --plain
        Explicitly select unencrypted IRC. The usual default plain port is
        6667. Automatic authentication is refused with this transport.
    --ca-file FILE
        Use an explicit PEM certificate authority file for TLS verification.
        Its authorities are trusted in place of the system default store.
    --no-connect
        Start all server sessions without connecting. In test mode, leave
        all simulators stopped. Use /connect for the current server, or
        Connect in the Servers list, when ready.
    --test-mode
        Load normal settings and run interactive, bounded IRC simulation
        inside this process. No sockets, DNS, or credential reads are used.
        Missing server/nickname values do not prompt. See OFFLINE TEST MODE.
    --init-config
        Create a configuration file and exit. Existing files are not
        overwritten. Combine with --server, --channel, and --nick to write
        initial connection values.
    --check-config
        Validate the primary configuration, command-line values, adjacent
        server catalog, and referenced profiles, then exit. This does not
        test server reachability or prove credentials work.
    --manual
        Write the complete manual to standard output and exit.
    -h, --help
        Write command-line help and exit.
    -v, --version
        Write the program version and exit.
    -V
        Compatibility alias for --version.

Long options accept --name=value. Short options accept the normal combined
option syntax. -- ends option parsing; positional arguments are not used.
Command-line values override the selected configuration, which overrides
built-in defaults. Explicit --port is available when a network uses a
different port from the transport's usual default.
Selecting a different --server clears inherited account/server-password
settings and inherited auto-join channels; specify channels for that server.
Additional servers have separate saved profiles. A different --config path
selects a different primary configuration and workspace catalog.

-h, -v, --manual, and --check-config exit without an interactive terminal
or welcome screen. --test-mode cannot be combined with --init-config or
--check-config; either combination is a usage error (exit status 2).

OFFLINE TEST MODE

    vipirc --test-mode
    vipirc --test-mode --config /absolute/config.ini
    vipirc --test-mode --no-connect

The simulator loads the selected configuration and runs the actual
interface, input editor, filters, and applicable protocol/queue handling.
It produces bounded synthetic IRC activity and membership changes. It
opens no network socket, performs no DNS lookup, and reads no password or
CA file. Configured servers are display labels; nothing is sent there.
The primary and saved secondary profiles each run separate simulations.
Servers > New adds more simulated sessions, without changing this mode.

After the welcome screen is dismissed, simulation starts even when the
configuration has autoconnect=false. --no-connect leaves all simulators
stopped until explicitly connected. /disconnect stops the current simulator;
/connect starts only that session's simulation. To connect to a real server,
exit and relaunch without --test-mode.

Missing server and nickname values do not cause prompts. The nickname uses
the Unix login name when valid, or a test nickname otherwise. Configured
channels are used; if none are selected, #test-one and #test-two are supplied.
Server/MOTD remains channel 0. The client starts in Navigation: c opens
channels, q opens queries, m opens mentions, and u toggles the user list.
Tab begins typing and returns to Navigation; main Escape opens Settings. /channels and /ql also
open the lists; /pm NICK opens a query.

Try fixed-height input, Backspace across rows, resize, paste, the immediate
message-limit warning, and multi-message send confirmation. Inspect
mentions and user lists while simulated events arrive. The same
retained-history bounds and applicable message queue and pacing rules apply.
The local simulator is part of the C client and does not require Python
or an external IRC daemon.

The scheduled event interval is two seconds. A cycle includes channel text,
a nickname mention, a configured custom watch string, a private message,
and a participant joining, changing nickname, receiving voice, and leaving.
All current custom watch strings are tried in rotation, one string per
16-second activity cycle. /watch changes affect the next watch event.
For a stable list of k strings, the sequence repeats every 16*k seconds.
If no custom watch string is configured, the demo gives a /watch example.
/msg NICK TEXT produces a labelled simulated private reply. Channel text
is locally echoed. JOIN, PART, NICK, WHOIS, TOPIC, and AWAY receive simulated
responses; the simulator does not implement every IRC server behavior or
enforce keyed-channel access.

File transfers displays a memory-only sample offer. You can review, reject,
or cancel it; Send and Accept are disabled before any file or socket access.
Closing a secondary test server removes only its runtime row, leaving saved
catalog and profile files unchanged.

/save is disabled in test mode. Interface changes remain in memory and
cannot overwrite real connection settings through that command. To try a
permanent configuration edit, edit the file with your text editor and
restart. This mode does not create or modify a config file automatically.

--check-config is a separate noninteractive syntax/value check. It reads
the primary configuration, catalog, and referenced profiles, reports the
result, and exits. --test-mode
adds interactive inspection of simulated behavior. Neither validates a
real hostname's reachability, TLS certificate, SASL identity, password,
authentication-service behavior, or actual delivery to IRC users.

MODES AND ACTIONS

The client starts in NAVIGATION with the original keymap. Both original
and the optional Vim-style preset start in Navigation. The top row shows
mode, keymap, and connection state before other details. The next row
identifies the current view; the third row holds the focused toolbar:

    Servers    Channels    Queries    Mentions    Users    Actions

Left/Up moves focus to the previous control; Right/Down moves it to the
next. Enter activates the highlighted control. Servers opens the server
list; Channels and Queries open the current server's respective choosers;
Mentions opens its collected matches; Users toggles the channel roster;
Actions opens the menu. Initial focus is Channels for configured/channel
startup, otherwise Servers. Every server retains its own main view and draft.
A narrow toolbar scrolls around its focused control with clickable side arrows.

Tab on the main chat screen focuses INPUT without sending. Printable text
edits the draft, and Enter submits it while staying in Input. Tab preserves
the draft, cancels selection, and returns to Navigation. Escape on the main
screen opens Settings from either mode, preserving the draft and cancelling
selection. In Navigation, Enter activates focus; Tab switches input focus.

Other original-keymap actions on the main Navigation screen:

    Page Up / Page Down    scroll history
    Home / End             oldest / newest retained history
    ?                      open Actions
    Esc                    open Settings
    c / q                  open channels / queries
    m                      open mentions
    0 / s                  open the current server's MOTD view
    S                      open the Servers list
    u                      toggle the user list
    x                      clear the entire current draft
    a                      select the entire draft and enter Input
    h                      open Help (original keymap)
    n / p                  next / previous view
    r                      redraw
    /                      enter Input; insert / only if the draft is empty

The slash action preserves a nonempty draft unchanged. These mnemonic
aliases remain available alongside the graphical focus controls.

The optional Vim-style preset changes the following main-view keys:

    h / k                  focus the previous toolbar control
    l / j                  focus the next toolbar control
    i                      enter Input, in addition to Tab
    g / G                  oldest / newest retained history

Other main-view aliases remain shared except h, which is Help only with
original keys. Use Actions > Help, /help, or /manual in either preset.
Input editing is identical. This is a navigation preset, without Vim editing operators
or full Vim compatibility.

    /keymap                report the current preset
    /keymap original       select original keys (the default)
    /keymap vim            select Vim-style navigation

/keymap changes the preset without changing the current mode. Its submitted
command draft clears normally. The config setting is [interface]
keymap=original or keymap=vim. /save preserves the choice in normal operation;
test-mode changes remain in memory.

Open Actions by focusing its toolbar control and pressing Enter, clicking
it, or using ? in Navigation. Up/Down selects an item; Enter or a
mouse click activates it:

    Type/edit draft
    Channels (server is 0)
    Queries
    Mentions
    Server/MOTD
    Toggle user list
    Clear input
    Select all input
    Toggle mouse
    Use Vim-style navigation / Use original keys
    Use bracket focus / Use reverse focus
    Help
    Connect/Disconnect
    Set away / Return from away
    Ignored senders...
    File transfers...
    Quit

The keymap and focus-style entries offer the alternative to the active
setting. They preserve drafts and return to Navigation. Type/edit draft
and Select all input enter Input. Other non-exit actions remain in
Navigation, with list/editor actions opening their named secondary screen.
Connect/Disconnect applies to the current server; Quit exits the workspace.
Escape or Back returns to the chat screen.
With Vim-style keys, j/k selects menu items, h goes back, and l activates;
g/G selects the first/last item. Arrows and Enter remain available.

Tab stays inside secondary screens, including Actions, Help / Manual,
server/conversation lists, Settings, and File transfers, showing:

    Input is on the chat screen. Press Esc to return.

Return with Escape, then use Tab to focus Input on the main screen.
Menus, the manual reader, and confirmation dialogs ignore bracketed paste.
On main Navigation, bracketed paste enters Input as literal draft text. Pasted tabs become
spaces and never change focus. Warning and confirmation prompts ignore Tab
until acknowledged with their displayed keys.

FOCUS APPEARANCE

Focused controls, chooser rows, and menu entries use reverse video by
default. Actions > Use bracket focus selects bracket highlighting;
Actions > Use reverse focus restores reverse video. The config setting is
[interface] focus_style=reverse or focus_style=brackets. This preference
styles navigation focus; it does not alter input-text selection highlighting.
/save preserves the setting in normal operation. Test-mode changes stay in
memory. Both styles use the same keyboard and mouse behavior.

SETTINGS

Escape on the main chat screen opens Settings for the current server from
either Input or Navigation. Edits remain staged until Apply or Save. The panel scrolls
through labelled fields. Up/Down selects a field; Left/Right selects its
footer action; Enter activates that action. Vim j/k selects fields and
h/l selects footer actions. Home/End reaches the first/last field.

    Edit    Apply    Save    Cancel

The editable groups contain:

    Startup: Server, Port, Verified TLS, Nickname, Username, Real name,
      Auto-join channels, Auto-connect, Authentication (none/sasl),
      Authentication user, Password file, Server password file, CA file.
    Interface: User list, Mouse, Navigation keys, Focus indicator,
      History lines.
    Mentions: existing Watch term fields and Add watch term.
    Ignore: existing Ignore mask fields and Add ignore mask.

Edit toggles a boolean checkbox, opens a two-option choice selector, or
opens a text/number field editor. Enter in an editor stages that field;
it does not Apply, Save, or send chat. Editing an existing watch term to
empty removes it; Add watch term creates another, within the usual bounds.
Ignore mask fields work the same way; an empty existing mask removes it.

Apply validates the staged configuration. It applies interface preferences,
mention terms, ignore masks, and auto-connect in memory, stays in Settings,
and resets the footer action to Edit. The applied values become the new
base for further edits. Apply does not write a configuration file.

Server, transport, identity, auto-join, authentication, and CA changes are
pending startup settings. Save them and restart the program to use them.
They do not change the active connection or the settings used by /connect
in this process. Use /nick, /join, and /part for current-session changes.
/save preserves pending startup choices while saving live preferences.

Save validates and atomically writes this server's full configuration,
then applies live preferences and returns to main Navigation. The first
Save of a new secondary server also creates its isolated profile and startup
catalog entry. Other servers' configurations are not overwritten.
In --test-mode, Save is
disabled; Apply previews changes only in memory. Edit the file externally
and restart to make permanent test-mode configuration changes.

Cancel or Escape closes the entire Settings panel, including from a field
editor or choice popup. Unapplied changes are discarded without another
question. Applied preferences and pending startup values remain in memory;
chat drafts remain intact. Escape from any secondary screen returns to
main Navigation; another Escape there opens Settings. Tab stays in Settings
and displays the return-to-chat instruction.

Changing Server to a case-insensitively different value clears inherited
Authentication, Authentication user, Password file, Server password file,
and Auto-join channels immediately in the staged form. Enter the intended
credentials and channels after choosing the new server. The active session
is untouched. Credential fields contain file paths; Settings does not read
or display password-file contents.

Bracketed paste is accepted only while a text/number field editor is open.
It inserts data without committing or closing the field. Tabs become spaces;
CR, LF, Escape, and unsupported control characters are rejected. Paste on
the Settings list or in a choice popup is ignored. Review pasted values,
then press Enter to stage the field. Warning and confirmation dialogs keep
their own cancel/acknowledgment behavior before the Settings shortcut.

TERMINAL SIGNALS

Ctrl-D is ignored, including when the draft is empty. To exit normally,
use /quit in Input mode or choose Actions > Quit. Custom terminal signal
assignments still take precedence over ordinary key handling.

Unix terminal signal keys remain available. The usual Ctrl-C interrupt
exits without saving drafts; Ctrl-Z suspends the process, and the shell's
fg command resumes it. A suspended client cannot answer the server and may
time out.

SERVERS AND UNREAD ACTIVITY

Up to eight server sessions share this process and terminal. Each has
independent configuration, credentials, nicknames, channels, queries,
mentions, users, retained history, drafts, and cursor/scroll positions.
Background connections keep receiving messages and answering protocol
traffic through the same event loop.

Activate Servers on the main toolbar, use Navigation S, or enter /servers.
Up/Down selects a server; Left/Right selects the footer action:

    Open    New    Connect    Disconnect    Close    Back

Enter executes the action for that row. Open switches to the server's last
main view in Navigation, keeping its draft. Connect and Disconnect act on
the selected server. New, also available as n in the list, opens the new
server form. Back or Escape returns to chat; Tab stays in the list. Vim
j/k selects rows, h/l selects actions, and g/G selects the first/last row.
Mouse row clicks open a server, and footer clicks apply to the selected row.

The primary server is entry 0 and cannot be closed. Disconnect keeps its
views, history, and drafts; accepted direct file transfers continue. A
secondary Close always asks first and defaults to no. Confirming discards
that server's drafts/history, cancels its offers/transfers, and removes its
saved startup catalog reference while keeping the physical profile file.
Closing the current secondary returns to the primary main screen. In test
mode, Close affects only runtime state and never changes saved files.

New server form

Basic fields are Server, Port, Verified TLS, Nickname, Auto-join channels,
and Auto-connect. Its footer is:

    Edit    Add    Connect    Advanced    Cancel

Use Edit to change the selected field. Advanced expands the form to all
startup connection fields, including Username, Real name, Authentication,
Authentication user, Password file, Server password file, and CA file.
This allows credentials to be configured before a first connection. The
Advanced button becomes Basic when expanded. Enter in a field only stages
its value; Escape cancels the whole form. Field paste follows Settings rules.

Fresh servers default to verified TLS on port 6697, a valid Unix login
nickname/username or fallback, and no authentication, credential-file paths,
CA override, channels, watch strings, or ignore masks. Only interface
preferences copy from the primary profile. Auto-connect defaults to false.

Add validates and creates a disconnected session, even if Auto-connect is
checked. Connect validates, creates, and connects immediately. Both switch
to the new server's main screen. Neither writes configuration. Use /save or
Settings > Save explicitly to retain this profile across launches.

Activity indicators

Server, channel, and query rows start with new N !M: unread activity and
unread mentions. The ! marker is explained in the list header. Counts above
999 display as 999+ while the internal counters remain exact. The main
Servers control also signals background activity.

Showing a main conversation clears only that source view's counts. A list
covering the current conversation does not mark arriving text read. Server
totals aggregate source server/channel/query views and exclude the copied
Mentions feed and Manual, avoiding duplicated counts. Opening Mentions
marks its feed read independently and does not clear source conversation
counts. Outgoing local echoes do not add unread activity.

VIEWS AND USERS

Every server has its own server/MOTD entry 0, channel list, query list,
mentions feed, and rosters. Channel and query headers identify their server.
The server view contains registration, MOTD, connection, and error messages.
Each channel or private conversation has a separate view. The mentions view
collects matching received lines with their original displayed timestamps,
source conversation, sender, and full message text. A long line wraps in
the display; the line's stored text remains complete within protocol bounds.

    /servers               open the workspace's server list
    /server                switch to the current server's MOTD view
    /mentions              switch to the mentions view
    /channels              open the numbered channel chooser
    /channel N             switch by channel-chooser number; 0 is server
    /channel #NAME         switch to an open named channel
    /ql                    open the separate query list
    /pm NICK               open/switch a private view without sending text
    /next                  next view
    /prev                  previous view
    /users                 toggle the channel user list
    /users on              show the channel user list
    /users off             hide the channel user list
    /users up              scroll the channel roster upward
    /users down            scroll the channel roster downward
    /mouse [on|off]        toggle mouse controls, or explicitly enable/disable
    /keymap [original|vim] report or change the navigation preset
    /clear                 clear the current view's stored lines

Navigation m opens mentions; u toggles the user list. The user list belongs
to the current channel; server and private conversation views do not have
a channel roster. A small terminal may hide the sidebar to leave usable
space for the conversation. Expanding the terminal makes room for it again.
User list membership follows server JOIN, PART, QUIT, NICK, KICK, and NAMES
messages. Network-defined privilege prefixes identify channel privileges.
Incoming private messages create a new query view only while fewer than
eight query views exist. Further unsolicited queries remain visible with
full context in server and mentions. Explicit /pm or /msg can create more query
views, subject to the per-server 32-view limit.

CHANNEL CHOOSER AND CLOSING CONVERSATIONS

Activate Channels on the main toolbar, use Navigation c, or enter /channels.
Entry 0 is always this server's MOTD view. Other entries are its channel views,
including channels you have left whose history remains available.

Up/Down selects a row. Left/Right selects an action on the related bar:

    Open    Join    Part    Close    Back

Enter executes the highlighted action for the selected row. Open is the
initial action. Join prepares /join in Input while preserving existing
drafts. Part leaves a channel while keeping its history; Close removes its
view. Part and Close reset the active action to Open. Back or Escape
returns to the chat screen in Navigation. Tab stays in the chooser; return
with Escape, then use Tab to type on the chat screen.

With Vim-style keys, j/k selects rows, h/l selects actions, and g/G selects
the first/last row. Direct aliases remain: p parts, c closes, and original
j or Vim o prepares a join. A mouse click on a row opens it; clicking an
action applies it to the selected row. On narrow screens, the bar shows
the current action with left/right arrows.

Closing a joined channel first requests PART. Its retained history and
draft are removed, and queued chat for that destination is cancelled; one
already in-flight message may finish. If the chooser would discard a
nonempty draft, a confirmation defaults to no. The server entry cannot be
parted or closed. Use /disconnect to end its connection.

/close [NAME|CHANNELNUMBER] also closes a channel or private conversation;
without an argument it closes the current conversation. Server and mentions
views cannot be removed; use Back or Escape to return from Help / Manual.
Channel-chooser numbers belong to /channel and /close. Numbers can change
after closing a channel; use
the current list when selecting by number. /views is an alias for /channels;
/view N uses the same channel numbering, and /view NAME selects a named view.

QUERY LIST

Activate Queries on the main toolbar, use Navigation q, or enter /ql.
The list contains only this server's private conversations, with no server,
channel, help, or mentions entry. Up/Down selects a row; Left/Right selects an action:

    Open    New    Close    Back

Enter executes that action. Open is the initial action; New prepares /pm
in Input while preserving drafts. Close removes the selected query and
resets the active action to Open. A close that would discard a nonempty
draft asks first, defaulting to no. Back or Escape returns to the chat
screen in Navigation. Tab stays in the list; return with Escape, then use
Tab to type.

With Vim-style keys, j/k selects rows, h/l selects actions, and g/G selects
the first/last row. Direct aliases are c for Close and original n or Vim o
for New. Clicking a row opens it; clicking an action applies it to the
selected row. A narrow bar shows the current action and side arrows.

/pm NICK opens or selects a private conversation without sending anything,
including while disconnected.
Enter Input mode to type after switching, or use /msg NICK TEXT to send
directly.
Private conversations are displayed and selected by nickname. Close one
by its name with /close NICK.

MENTIONS AND WATCH STRINGS

Your current nickname is watched automatically. Nickname matching follows
the IRC server's advertised case mapping and nickname boundaries. A nickname
change updates this automatic match.

    /watch add project name
    /watch remove project name
    /watch list

Custom watch values are literal substrings, not regular expressions or
shell patterns. IRC/ASCII letter and symbol case rules are used; non-ASCII
characters match exactly. Up to 32 custom values of 127 UTF-8 bytes each
are accepted. Use /save during normal operation to preserve changes in the
selected configuration. In test mode, changes remain in memory.
Mentions are retained in memory, subject to the history limits. They are
not a permanent notification archive or an on-disk log.
Timestamps are local receipt dates and times, in YYYY-MM-DD HH:MM:SS form.

CONVERSATION COMMANDS

    /join CHANNEL [KEY]     request to join one channel, optionally with a key
    /part [CHANNEL]        leave a specified channel or the current channel
    /close [NAME|NUMBER]   close a channel/query; number is a channel number
    /pm NICK               open/switch a private view without sending text
    /msg TARGET TEXT       send text to one nickname or channel
    /me TEXT               send an IRC action to the current conversation
    /nick NICK             request a different nickname
    /away [MESSAGE]        set away with text; without text, clear away
    /back                  clear away status; takes no argument
    /whois NICK            request information about a nickname
    /topic                 request the current channel topic
    /topic TEXT            request a new current-channel topic
    /connect              connect the current server with its active settings
    /disconnect           disconnect this server, keeping its views/drafts
    /dcc or /transfers     open the shared File transfers screen
    /cancel               discard queued chat not yet being transmitted
    /quit                 exit all server sessions and transfers
    /save                 write current settings; disabled in test mode
    /set autoconnect on    enable connection at future startup after saving
    /set autoconnect off   disable it

/away MESSAGE sends one standard AWAY message. Text is limited to the
current wire limit minus 8 bytes (504 bytes at the usual 512-byte limit);
oversized text or controls are rejected, never split. /away with no text
and /back clear away. These require registration. The indicator changes
only on server acknowledgments and resets on disconnect/reconnect.
Actions > Set away sends Away as the message, preserving the view and draft.
Return from away clears away status. Away status (disconnected) asks you to
connect first. Ignored senders... opens its Settings group for staged edits.

/join accepts one channel and at most one key token. Keys must be printable
ASCII without spaces, colon, or comma, and the complete JOIN must fit the
wire limit. The key is not logged or saved; only the channel name enters
auto-join. Re-enter the key when needed after reconnecting or restarting.
The offline simulator acknowledges away changes and accepts transient
join keys, but does not test a real channel's key or admission policy.

The server decides permissions, nickname availability, channel admission,
and whether topic changes are allowed. Local command acceptance does not
guarantee server acceptance or delivery to another participant.
/cancel cannot recall a message already transmitted; one in-flight message
may still finish. /join and /part update the auto-join selection; /save
preserves that selection for future launches unless pending Settings startup
choices override it.
/part also discards queued text for that channel while retaining the view
and its history. A message already in flight may finish before PART.

LOCAL IGNORE FILTERS

    /ignore or /ignore list       list masks in the server view
    /ignore MASK                 add a mask; /ignore add MASK also works
    /unignore MASK               remove it; /ignore remove MASK also works
    /ignore clear                remove all masks

These local commands work disconnected. Use /ignore add NICK for nicknames
literally named list, add, remove, or clear. Up to 32 masks of 127 ASCII
bytes each are accepted. A plain mask must be an exact valid nickname.
Wildcards require full nick!user@host form with three nonempty components;
for example, *!*@*.example. Within each component, * matches zero or more
bytes and ? matches one byte. Other permitted bytes are literal; there are
no regex classes, escaping, or shell expansion. Nick uses IRC case rules;
user and host ignore ASCII case. Whitespace, controls, and non-ASCII are invalid.
Removal compares stored patterns under those case rules; it does not expand
wildcards to remove other masks.

Only incoming user-originated PRIVMSG/NOTICE is filtered, before mentions
or query creation. A source needs an explicit user prefix; nickname-only
masks can match incomplete user/host details, while full masks require all
three parts. Bare server notices and all protocol/membership state remain
visible. Existing history is retained. Filtering is local, not a server ban.
Settings edits the same list; Apply acts live. /save or Settings Save persists
it in normal mode; test-mode edits stay in memory. Config repeats mask= in
[ignore].

FILE TRANSFERS

/dcc, /transfers, and Actions > File transfers... open the same global
transfer screen. Records identify their originating IRC server. Up/Down
selects a transfer; Left/Right selects an action; Enter executes it:

    Accept    Reject    Send...    Cancel transfer    Back

Vim j/k selects rows, h/l selects actions, and g/G selects endpoints. Mouse
rows select records and action clicks execute the selected action. The
screen needs at least 12 rows by 20 columns for transfer review. Escape from
any transfer screen returns directly to main Navigation without discarding
chat drafts or stopping accepted transfers. Tab stays in the panel.

This release supports active classic IPv4 DCC SEND only. It does not support
DCC CHAT, resume, passive/reverse transfers, automatic acceptance, automatic
address discovery, or automatic port forwarding. A transfer can contain at
most 4,294,967,295 bytes. Received files are never opened or executed for you.

DCC transfers are unencrypted direct peer connections, independent of IRC
TLS. The protocol does not cryptographically authenticate a connecting peer.
An outgoing offer discloses its advertised IPv4; accepting an offer reveals
the receiving host's IP to the peer. Check the sender, intended file, byte
size, and displayed endpoint before approving each transfer.

Receiving

An incoming offer is stored without opening any file or socket. Reject
refuses it without creating either. Accept in the list opens a review form
with Directory and Save as fields and this footer:

    Edit    Accept    Cancel

Review the peer endpoint and size, edit the destination if needed, then
choose the form's Accept to start. Enter in a field stages it; it does not
accept the offer. Cancel returns to the list. Field paste inserts data only;
unsupported controls cannot commit it. Paste outside a field is ignored.

The default directory is $XDG_DATA_HOME/vipirc/downloads when XDG_DATA_HOME
is absolute, otherwise $HOME/.local/share/vipirc/downloads when HOME is
absolute. Without an absolute base, enter a destination explicitly. Missing
destination ancestors are created with mode 0700 only after Accept. The
final directory must be private and owned by you. A new regular file uses
mode 0600; existing files, symlinks, and '..' paths are refused.

The offered or chosen basename must be visible and nonhidden, with no path
separators, control/bidirectional-formatting characters, or quotes. Quoted
wire filenames may contain internal spaces. Failed or cancelled partial
files are removed only if they still identify the file created for that
transfer; a replacement file is not removed.

Sending

Select Send... to open a form containing Nickname, Source file, Advertised
IPv4, and Listen port. A current query supplies its nickname as a default.
The form names the IRC server through which the offer will be sent. Its
footer is Edit, Offer, Cancel. Offer explicitly starts the listener and
queues the offer through that registered server's paced chat path.

Source file must identify an existing regular file; symlinks and '..'
components are refused. Prefer an absolute path. Enter the IPv4 address the
receiver can reach. Listen port 0 chooses an available local port; an
explicit value is from 1 through 65535. Behind NAT, use the appropriate
advertised address and a forwarded port. vipirc does not discover the
public address, configure UPnP, or arrange forwarding.

With SSH, all paths, HOME/XDG download directories, listening/advertised
addresses, and peer connections belong to the host running vipirc. That
may be the remote SSH host. The terminal emulator's local filesystem and
network address are not used for these transfers.

Lifecycle and bounds

Accepted transfers continue while chatting, switching servers, or
Disconnecting IRC. Cancel transfer stops one transfer. Closing its server
cancels that server's offers and transfers; quitting stops all of them.
Cancellation, failure, or expiry also removes a still-queued outgoing
offer. An offer already sent or in flight cannot be recalled.

The workspace permits eight pending offers, four active/listening/connecting
transfers, and twelve retained transfer records in total. Completed or failed
records are recycled oldest-first only when full; transfer IDs are not
reused during a run. Pending offers expire after five minutes. Transfers
stop after two minutes without progress. File data is streamed in bounded
buffers, with cumulative 32-bit acknowledgments.

In --test-mode a memory-only sample offer permits list/reject/cancel review.
Send and Accept are disabled before any filesystem or socket access. Real
file transfers require restarting without --test-mode.

INPUT EDITING

These keys apply in Input mode:

    Enter                  send or review the composed text
    Left                   previous character group
    Right                  next character group
    Up / Down              move between wrapped visual input rows
    Home                   beginning of the complete composition
    End                    end of the complete composition
    Backspace              remove the previous character group
    Delete                 remove the character group under the caret
    Tab                    preserve draft, cancel selection, enter Navigation
    Esc                    preserve draft, cancel selection, open Settings

Typed Enter submits; explicit newlines can be composed through bracketed
paste. Pasted tabs become spaces without changing focus. Navigation x or
Actions > Clear input clears the entire current draft, including offscreen
text. The clickable [Clear] input-status control
does the same without changing the current mode. Clearing never sends text.
The menu clear action returns to Navigation.

Navigation a or Actions > Select all input selects the entire draft and
enters Input, including text outside the visible input area. The first valid
typed or pasted character replaces selected text; an empty or wholly
rejected paste preserves the text and selection.
Backspace or Delete clears selected text. Tab cancels selection and returns
to Navigation. Escape cancels selection and opens Settings. Both keep the draft. Left and Right cancel selection at its
beginning or end; Up/Down cancels selection before visual-row movement.
Home/End move to the complete draft's endpoints and cancel selection.
Selection is for editing inside the client; it does not transfer text to
a clipboard.

The composition is a flat logical buffer. Screen wrapping does not insert
characters. Backspace at the beginning of a wrapped row removes the last
character of the preceding row. Resizing the terminal retains the text and
cursor position.

Input height is fixed for the current view and its protocol byte budget.
For B ordinary-message payload bytes and W usable terminal columns, it
reserves floor(B/W)+1 rows, including the caret cell. W is the terminal
width minus one. A budget of 465 bytes at 99 usable columns reserves five
rows. On a small usable screen, the height is clamped to leave at least
three history rows. Views without a chat recipient use a one-character
recipient allowance when calculating their height.

Typing, deleting, and composing /msg or /me do not grow or shrink the input
area. Longer drafts scroll within it to keep the caret visible. A terminal
resize, view switch, or actual protocol-budget change recalculates the
height. The draft and cursor position remain intact.

UTF-8 is used for input and messages. Set a UTF-8 locale so the terminal and
the curses library agree about display widths. ASCII is already its
one-byte subset; no manual encoding switch is needed. SSH does not
change the encoded message length. On each remote host, inspect the session:

    locale
    locale charmap
    locale -a

The first two show locale settings and character encoding; locale -a lists
installed locales. The effective LC_CTYPE on the host running vipirc should
use an installed UTF-8 locale matching the terminal. Names vary across
systems, so check each SSH host. TERM identifies terminal capabilities,
not encoding. The client does not guess terminal encoding or transcode
legacy character sets.

The active LC_CTYPE is respected. A UTF-8 locale enables Unicode editing.
A non-UTF-8 or invalid locale selects ASCII terminal mode. The welcome
screen explains the mode, and a persistent marker identifies it. ASCII
typing works; non-ASCII input is refused with a clear status message.
Incoming non-ASCII code points display as '?' without changing the stored
network text. The client does not force a locale or change terminal
settings. Select an installed UTF-8 locale and restart for Unicode use.

A base character and its following zero-width marks move and delete
together. Full Unicode grapheme segmentation, including indivisible
multi-character emoji sequences, is not implemented. Unsupported glyphs
receive a visible replacement where needed.

The composition accepts up to 8,192 Unicode scalar values and 16,384 UTF-8
bytes. These are draft-storage bounds; the much smaller message budget
below determines warnings and splitting. The first storage limit reached
applies. Invalid UTF-8 and terminal controls are rejected. Pasted newlines
remain visible in the composition and are considered when calculating how
many IRC messages would be needed.

MOUSE CONTROLS

Mouse controls are enabled by default when curses and the terminal support
mouse events. /mouse toggles the preference; /mouse on or /mouse off sets
it explicitly. Actions > Toggle mouse also changes it. The config setting
is [interface] mouse=true or mouse=false. /save preserves the choice during
normal operation; test-mode changes remain in memory.

Click a main-toolbar control to focus and activate it. Click in the main
input area to place the caret and enter Input. [Clear] clears the whole
draft without changing the current mode. The toolbar remains visible when
mouse handling is off. Its clickable side arrows reveal controls when the
whole toolbar does not fit.

In a channel/query chooser, clicking a row opens it; clicking an action
applies it to the selected row. The wheel moves row selection. A narrow
action bar shows its active action and left/right arrows. In Actions,
clicking an item activates it. Back or Escape returns to the chat screen.
Tab stays inside these secondary screens and displays the return hint.

Over conversation history, each wheel step scrolls three visual rows;
over the user roster it scrolls three users. The main chat display needs
at least 9 rows and 20 columns. Its first row keeps mode and keymap visible,
its second identifies the view, and its third shows the focused toolbar.
Below 80 columns, offline sessions keep [OFFLINE] visible at the start of
the second row. Input height is clamped to leave three history rows.

The terminal and any SSH multiplexer must forward supported mouse events.
Availability depends on curses, TERM, and the terminal. Keyboard navigation
and editing remain available. Mouse actions do not send chat or acknowledge
safety prompts. The early length popup requires Enter or Escape and returns
to Input; later send confirmation uses its displayed keyboard choice.
Mouse controls do not open URLs or transfer clipboard text.

MESSAGE LENGTH AND FLOOD PREVENTION

Ordinary IRC protocol lines are limited to 512 bytes, including CR and LF.
That is a wire-line limit, not a limit of 512 user-visible characters.
ASCII uses one byte per character. A Unicode code point uses one to four
UTF-8 bytes, and a displayed glyph can contain multiple code points.
Command, destination, and relay prefix also take space. For a relayed
message of the form

    :nick!user@host PRIVMSG target :text<CR><LF>

the budget used by vipirc is

    B = L - (len(nick) + len(user) + len(host)
             + len(target) + len("PRIVMSG") + 9)

L is normally 512, reduced by a recognized smaller server LINELEN value.
Lengths in this expression are bytes. IRC actions have an additional
envelope, whose bytes are also subtracted. Until the full relay identity is
known, conservative identity allowances reduce B. Different destinations
and identity changes can therefore change the current payload budget.

While editing, a popup appears as soon as the longest logical payload line
reaches B bytes, or the draft already needs multiple messages:

    Message limit reached (B bytes).
    More text will need multiple chat lines.
    Enter/Esc: keep editing. Nothing sent.

If the draft already needs multiple messages, the middle line instead says
"This draft needs multiple chat lines." Enter or Esc returns to Input mode;
neither sends the draft. Other keys cannot dismiss the popup, and a short
key-repeat guard protects acknowledgment. The warning is shown once per
threshold crossing. Editing back to one message below the byte limit arms
it again. /msg, /me, and // are measured by their actual outgoing payload;
other local commands do not trigger this warning. Bracketed paste is
checked after the paste finishes and remains intact within the input bounds.

When Enter submits a composition needing more than one message, the client
presents a separate send confirmation:

    This text needs N IRC messages. Send all? [y/N]

Enter or n declines. Sending requires an affirmative y. Splits occur only
between complete UTF-8 characters, with nonempty message text preserved.
Explicit newlines separate messages; empty lines are skipped. No split is
sent before confirmation. Local slash commands must remain single-line;
compose multiline chat in the selected conversation instead.
Accepted chat messages are paced at least 1.2 seconds apart; the bounded
send queue holds at most 64 messages. Server flood rules can be stricter.
Protocol control traffic such as PONG is handled separately from chat.

The network can impose additional rules or reject messages. vipirc keeps
the ordinary 512-byte compatibility ceiling; it does not assume that a
server will accept a larger line merely because an extension exists.

CONFIGURATION

Generate an editable starting point:

    vipirc --init-config --server irc.ircnow.org --channel '#ircnow'

Edit the file with your preferred text editor. Validate it before launch:

    vipirc --check-config

One file describes one server profile. --config selects the primary
profile and its adjacent catalog of saved secondary profiles. Up to eight
server sessions share a process. Separate --config paths can still open
independent workspaces in different terminals.

Recognized sections and keys:

    [connection]
    server=irc.ircnow.org
    port=6697
    tls=true
    nick=tutankh-aten
    username=
    realname=vipirc user
    channel=#ircnow
    autoconnect=true
    auth=none
    auth_user=
    password_file=
    server_password_file=
    ca_file=

    [interface]
    user_list=true
    mouse=true
    keymap=original
    focus_style=reverse
    history_lines=500

    [mentions]
    word=project name
    word=another literal phrase

    [ignore]
    mask=spammer
    mask=*!*@*.example

The nickname and IRC username are different fields. An empty nickname is
prompted at interactive startup. The username defaults from your Unix
account. realname is the descriptive IRC USER field; it need not be your
legal name. channel is a comma-separated auto-join list, without spaces.
An empty channel value leaves you in the server view.

auth accepts none or sasl. With sasl, auth_user is the network account name
and password_file points to a separate secret file. server_password_file
is a separate optional server PASS password; it is not a nickname-account
password. Both authentication paths require verified TLS.

keymap accepts original or vim, default original. Both start in Navigation;
Input editing is identical. /keymap changes the in-memory choice, and /save
preserves it during normal operation. Test-mode changes remain in memory.
focus_style accepts reverse or brackets, default reverse. It styles focused
controls, chooser rows, and menu entries, leaving input-text selection
highlighting unchanged. Actions offers the same choice; /save preserves it
during normal operation.
history_lines accepts 50 through 5000 retained lines per view, default 500.
The additional per-server 8 MiB history text cap can evict older lines sooner.
Boolean values accept true/false, yes/no, or 1/0 in lowercase. Unknown
sections, unknown keys, invalid values, and oversized values are errors
with a configuration line number where applicable. Most duplicate keys
use the last value; repeated mentions word and ignore mask entries add values.

Lines starting with # or ; after leading whitespace are comments. There
are no inline comments: # inside channel=#ircnow is part of the value.
Leading and trailing value whitespace is trimmed. Quotes, backslashes,
environment-variable expansion, ~ expansion, and shell evaluation are not
configuration syntax. Paths are literal; prefer full absolute paths.
Settings Apply and configuration saving reject leading or trailing ASCII
spaces in text values, including watch phrases and credential-file paths.
This prevents a saved value from changing when reloaded. Interior spaces
remain valid where the field permits them. Hand-written INI padding keeps
the trimming rule above; quoting or escaping cannot preserve outer spaces.

/save during normal operation generates the whole selected configuration
again, preserving any pending startup choices applied through Settings. It preserves the supported settings, and replaces hand-written
comments and formatting.
Changes to the file are loaded at the next launch. Keep any explanatory
notes you want to retain outside the generated file.
The command is disabled in --test-mode; edit the file and restart instead.

Generated files have mode 0600. Their final parent directory must belong
to you and have mode 0700. Existing config files must belong to you and
must not be writable by other users. Symlinks in a config or secret path,
including directory components, and '..' path components are refused.

SAVED SERVER PROFILES

For primary path P, the adjacent P.servers catalog lists up to seven
secondary profiles in the private P.d directory. For the default path,
these are config.ini.servers and config.ini.d beside config.ini. Catalog
syntax is [servers] followed by repeated profile=ID entries. Generated names
use server-<24 lowercase hexadecimal characters>.ini. Manual IDs may contain
1 through 63 ASCII letters, digits, underscores, hyphens, or dots; the first
character must be a letter or digit, and consecutive dots are forbidden.
Directory components and arbitrary paths are not accepted as profile IDs.

Servers > New creates no file. Its first explicit /save or Settings Save
creates a separate mode-0600 profile in the mode-0700 directory and registers
it in the catalog. Subsequent saves update that server's profile. Saving
a secondary never replaces the primary configuration. Startup catalog
updates are locked. Invalid catalog/profile entries produce visible errors;
healthy profiles remain usable.

Close removes a secondary's catalog reference but keeps its profile file.
The primary cannot be closed. --check-config checks the selected primary,
catalog, and referenced profiles without connecting. Connection command-line
overrides apply only to the primary. --no-connect suppresses startup for
all profiles. In test mode, Save is disabled and Close changes runtime only.

AUTOMATIC CONNECTION, JOIN, AND AUTHENTICATION

An explicitly supplied or interactively entered primary server starts a
connection. Each saved profile with autoconnect=true connects at startup.
--no-connect overrides startup connection for all profiles. Without automatic
connection, /connect starts the current server; Connect in Servers starts
the selected row. Each server authenticates only with its own configuration.

The channel setting supplies the auto-join list. For automatic account
authentication, configure the account registered with that network:

    [connection]
    tls=true
    auth=sasl
    auth_user=your_registered_account
    password_file=/home/yourname/.config/vipirc/sasl.secret

Create the secret using a text editor. It contains only the password on one
line, optionally followed by one line ending. It must be your regular file
with no group or other permission bits: normally mode 0600, or 0400 for a
read-only secret. The password is limited to 1024 bytes. Do not put it in a
command-line argument, shell command, config value, or chat message.

SASL PLAIN is sent only after successful TLS verification. The server must
support that authentication method. Required authentication failure stops
the connection; channels are not silently joined under an unauthenticated
identity. The client does not register a nickname account on your behalf.
Nickname-service command formats are network-specific; automatic account
authentication in this release uses SASL.

SECURITY AND RESOURCE BOUNDS

TLS verifies the certificate chain and the requested hostname or numeric
address. There is no certificate-verification bypass or silent downgrade.
Plain IRC is available only through an explicit setting; it exposes IRC
traffic to observers on the connection path and cannot use saved secrets.
TLS protects the client-to-server connection, not end-to-end chat privacy.

Incoming IRC data is untrusted. Unsafe control sequences and formatting
are sanitized before display. Input and network buffers are bounded. The
client does not execute received text, launch URLs, run shell commands,
load scripts or plugins, or reply automatically to CTCP requests. Action
messages are displayed as text. DCC SEND offers require explicit per-file
review and acceptance; their direct connections are not encrypted by TLS.

Limits in this release:

    Server sessions per process           8
    Views per server, including builtins  32
    Users stored per channel           4096
    Custom mention strings per server     32
    Ignore masks per server               32
    Queued chat messages per server       64
    Retained history text per server   8 MiB
    Input Unicode scalars per draft     8192
    Input UTF-8 bytes per draft        16384
    Pending DCC offers, whole workspace    8
    Active DCC transfers, workspace        4
    Retained DCC records, workspace       12

The history cap applies per server, not as a total-process memory cap.
At eight sessions the maximum retained history text is 64 MiB. Server state
is allocated as needed; fewer sessions do not reserve eight full histories.
Libraries, view metadata, user lists, input, and transport use more memory.
History and mentions are not written to disk. Settings and secret files
are local files; other software with your account's privileges can read
them. No client can guarantee safety against every hostile server or a
compromised terminal, operating system, or library.

TROUBLESHOOTING

No connection: inspect /server for the concrete error. Verify the hostname,
port, network access, and whether the port actually offers TLS. /connect
retries manually. Verify a certificate failure's cause; do not send account
credentials over plain IRC to work around it.

Authentication failure: check the registered account name, secret file
ownership and permissions, and whether the network supports SASL PLAIN.
A server PASS password is separate from a nickname-account password.

Nickname rejected or in use: choose another nickname with /nick when the
server permits it, or save a new startup nickname and restart.

Empty channel view: inspect /server for join refusal, an invite-only or
restricted channel, or authentication requirements. /join requests a join;
it does not override server permissions.

Unusual text widths: use a UTF-8 locale, correct TERM setting, and a terminal
font with the desired glyphs. Unicode width choices can vary by terminal.
Use Tab to return from Input to Navigation, then r to redraw. Enlarge the
window if the sidebar or input is cramped.

Config save refused: use a private directory owned by your account, with
mode 0700, and a normal file path without symbolic links or '..'. /save
does not follow links to another file. Generated configuration is mode 0600.
In --test-mode, saving is deliberately disabled for the whole session.

PLATFORMS, BUILD, AND LICENSE

The target is Unix-like systems, including Linux in ChromeOS's Linux
environment and the BSDs. Requirements are a C11 compiler, POSIX interfaces,
a GNU/BSD getopt_long interface, wide-character curses, and compatible TLS
headers/libraries. There is no language runtime dependency for the client.
Python 3 is used for integration tests, not for ordinary chat.

    ./configure
    make
    make check-offline
    make check
    make install PREFIX="$HOME/.local"

See INSTALL for dependency and build details, SECURITY.md for the security
model and limits, and the release validation report for platforms actually
tested. Native BSD execution is a separate validation step; portability
intent is not evidence of having tested every Unix-like operating system.
make check-offline runs the CLI/PTY suite without a network socket. The
broader make check suite also uses local loopback fake servers.

This is an application of ThatIAm.vip (www.thatiam.vip), designed by remfan1994.
Source is available under the included IALA (Insha-Allah License Agreement),
whose full text is in LICENSE.md. Linked libraries keep their own licenses;
see NOTICE. The implementation was written for this specification without
copying another IRC client's implementation or configuration language.

PROTOCOL REFERENCES

    https://www.rfc-editor.org/rfc/rfc2812
    https://modern.ircdocs.horse/
    https://ircv3.net/specs/extensions/capability-negotiation
    https://ircv3.net/specs/extensions/sasl-3.1
    https://www.irchelp.org/protocol/ctcpspec.html
    https://www.irchelp.org/protocol/dccspec.html

IRC syntax and interoperability requirements come from protocol documents.
The program's interface and scope follow the project's requirements.
