# status line

In visual mode, the input and output windows are separated by a status line, which by default looks something like this:

      More 156_WorldName____________(Read)_(Active: n)_(Log)_(Mail)_(Over)_12:34

- "More" indicates how many more lines of text are waiting to be seen.
- "WorldName" is the name of the foreground socket's world.
- "(Read)" indicates that keyboard input is being read by read().
- The "(Active: n)" indicator shows the number of sockets with unseen text.
- "(Log)" indicates that there is one or more log file open.
- "(Mail)" or "Mail n" indicates the number of files named by %MAIL or %MAILPATH that contain unread mail.
- "(Over)" indicates that typed characters will overstrike instead of insert (that is, %insert is off).
- The current time is displayed at the right end of the status line.

# Configuring the status line

The status line is defined as a list of fields. A status field is defined as follows:

- an optional field name
- an optional ":" and number indicating the field width
- an optional ":" and attribute

The current list of status fields is stored in the status_fields variable, and the default list is stored in status_field_defaults. If you have changed status_fields, you can restore it to its default value by typing "`/eval /set status_fields=%status_field_defaults`". Except for restoring the default value, you should usually not set status_fields directly, but use the following commands instead.

`/clock off`
  Remove the clock from the status bar (equivalent to "`/status_rm @clock`").
`/clock on`
  Add a clock to the end of the status bar if there is not already a clock on the status bar. The width of the @clock field will be set exactly wide enough to hold a time formatted according to %clock_format.
`/clock [format]`
  Add a clock to the end of the status bar if there is not already a clock on the status bar; in either case, use format to control the format of the clock (see ftime() for the meaning of format). If format is omitted, it defaults to "%H:%M". The width of the @clock field will be set exactly wide enough to hold a time formatted according to format.
  Example: display a clock in 12-hour format:
  `/clock %I:%M`
`/status_rm name`
  Remove status field name from the status bar. If there are unnamed pad fields on both sides of the named field, the one with the smaller width is also removed; if the named field is at the beginning or end, the neighboring pad field (if any) is removed.
  Example: Remove the @mail field from the status bar:
  `/status_rm @mail`
`/status_add [options] name[:width[:attributes]]`
  Add status field name to the status bar with optional width and attributes. Options:
  -A
    add after all other fields (i.e., at end)
  -Afield
    add after existing field field
  -B
    add before all other fields (i.e., at beginning)
  -Bfield
    add before existing field field
  -sN
    insert padding of N spaces between the new field and the neighbor selected by -A or -B (default 1)
  -x
    don't add the field if one with the same name is already present
  If neither -A nor -B is given, -A is assumed.
  Example: Add a new field called "hp" after the world name:
  `/status_add -A@world hp:4`
`/status_edit name[:width[:attributes]]`
  If field name currently exists in the status bar, replace it with name[:width[:attributes]]. Neighboring padding is unchanged.
  Example: Change the @log field to say "L" instead of "(Log)", and change the field's width to match:
  `/set status_int_log=nlog() ? "L" : ""`
  `/status_edit @log:1`

The default list of status fields is:

      @more:8:Br :1 @world :1 @read:6 :1 @active:11 :1 @log:5 :1 @mail:6 :1 insert:6 :1 kbnum:4 :1 @clock:5

There are several types of fields:

- Unnamed fields create padding between the fields on either side of it. Each of the ":1" fields in the default status_fields puts a space of 1 character between the other fields.
- Field names beginning with "@" correspond to internal states. For example, "@more" will be updated whenever the number of unseen lines changes.
- Field names containing only letter, digits, and underscores correspond to variables. Whenever there is a change in the value of the variable with the same name, the field will be updated. The value an unset variable is considered to be the empty string. For example, whenever the %insert variable changes, the "insert" field is updated. Any variable may be monitored in this manner.
- A field whose name is in quotes (", ', or `) has its name (without the quotes) printed literally on the status bar, and is never updated. Use the \ character to escape a quote inside the string. The default status_fields does not contain any of these literal fields.

Any variable may be monitored, but there is a fixed list of internal statuses. The internal statuses available are:

`@more`
  Updated when there is a change in the number of lines below the bottom of the window.
`@world`
  Updated when when the foreground world changes. During the format expression, the current socket is the new socket.
`@read`
  Updated when entering or exiting a read() function call.
`@active`
  Updated when the number of active worlds changes. During the format expression, the current socket is the socket that became active.
`@log`
  Updated when the number of open log files changes.
`@mail`
  Updated when mail arrives (See "mail").
`@clock`
  Updated every minute, at 0 seconds past the minute.

Also, the entire status line will be updated whenever the screen is redrawn, any of the /status_{add,rm,edit} commands are called, or the status_fields variable is modified.

A field's width determines how many columns it will take up on the screen. If the width of a string literal field field is omitted, it defaults to the length of the string literal. One other field width may be omitted, which means that field will use whatever columns are unused by the other fields. Normally, fields are left-justified within the width, but a negative field width will right-justify the field within the absolute value of the width. If the formatted text is wider than the field width, it will be truncated to fit within the specified width. Fields may also be truncated if they would not fit on the screen.

The attributes explicily given in the field definiton are combined with those in the corresponding `%status_attr_int_fieldname` (for internal state fields) or `%status_attr_var_varname` (for variable fields). The combined attributes are applied to the field text when it is displayed, but not to the padding used to bring the field to the specified width. The entire status line, including padding, is displayed with the attributes given by %status_attr, which is none by default.

To bring fields up to their specified width, they are padded with %status_pad, which is "_" by default. By setting status_pad to " " and status_attr to "r", you can create a status line that looks more like the one in emacs or the irc client.

When a status field is updated, the text displayed for that field is determined by evaluating the expression contained in the variable `status_int_name` (for internal state `@name`) or `status_var_name` (for variable `name`). Also, for variable fields, if `status_var_name` is not set, the value of the variable will be displayed directly. Changing a format variable will cause the status line to update.

All this may sound rather complex, so an example might help. The default value of status_fields is:

      @more:8:Br :1 @world :1 @read:6 :1 @active:11 :1 @log:5 :1 @mail:6 :1 insert:6 :1 kbnum:4 :1 @clock:5

and the corresponding format variables are:

      /set status_int_more \
           moresize() == 0 ? "" : \
           moresize() > 9999 ? "MuchMore" : \
           pad("More", 4, moresize(), 4)
      /set status_int_world   strcat( \
           fg_world() !~ "" & !is_open(fg_world()) ? "!" : "",  fg_world())
      /set status_int_read    nread() ? "(Read)" : ""
      /set status_int_active  nactive() ? pad("(Active:",0,nactive(),2,")") : ""
      /set status_int_log     nlog() ? "(Log)" : ""
      /set status_int_mail \
           !nmail() ? "" : \
           nmail()==1 ? "(Mail)" : \
           pad("Mail", 0, nmail(), 2)
      /set status_var_insert  insert ? "" : "(Over)"
      /set status_int_clock   ftime(clock_format)

The first field is "`@more:8:Br`". So, whenever the number of unseen lines changes, TF looks for the variable `status_int_more`, and evaluates the expression it contains. The result of the expression is printed in the first 8 columns of the status line, with attributes "Br" (bold and reverse). The expression was carefully written so that it will never be more than 8 characters, because it would be confusing to generate something like "`More:12345`" and then have it truncated to "`More:123`" because of the field width of 8.

Since the "`@world`" field has no explicit width, its width is determined dynamically. The fields on its left are pushed to the left side of the screen, the fields on its right are pushed to the right side of the screen, and the "`@world`" field uses whatever space remains in the middle.

Another example: Say your mud has a prompt like "`H:42 M:17>` " that shows your hit points and mana, and you want it displayed on the status line like "`42, 17`", after the world name. To do this, call "`/status_add -Aworld hp_mana:7`", and define a prompt hook:

      /def -mregexp -h"PROMPT ^H:([^ ]*) M:([^ ]*)> $" hp_mana_hook = \
          /set hp=%P1%; \
          /set mana=%P2%; \
          /set hp_mana=$[pad(hp, 3, ",", 0, mana, 3)]%; \
          /test prompt({*})

See: visual

Back to index
Back to tf home page

Copyright © 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004 Ken Keys