Manpage logo

cha-config -

Configuration of Chawan  Start  Buffer  Search  Encoding  External  Input  Network  Display  Status  Omnirule  Siteconf  Keybindings  Pager actions  Buffer actions  Line−editing actions  Appendix  Regex handling  Match mode  Search mode  Path handling  Word types  w3m word  vi word  Big word  See also 

Configuration of Chawan

Chawan supports configuration of various options like keybindings, user stylesheets, site preferences, etc. The configuration format is similar to toml, with the following exceptions:

Inline tables may span across multiple lines.

Regular tables ([table]) and inline tables (table = {}) have different semantics. The first is additive, meaning old values are not removed. The second is destructive, and clears all definitions in the table specified.

[[table−array]] is sugar for [table−array.n], where n is the number of declared table arrays. For example, you can declare anonymous siteconfs using the syntax [[siteconf]].

The canonical configuration file path is ~/.chawan/config.toml, but the search path accommodates XDG basedirs as well:

1.

config file specified through −C switch −> use that

2.

$CHA_DIR is set −> use $CHA_DIR/config.toml

3.

${XDG_CONFIG_HOME:−~/.config}/chawan/config.toml exists −> use that

4.

~/.chawan/config.toml exists −> use that

See the path handling section for details on how the config directory can be accessed.

Start

Start−up options are to be placed in the [start] section.

Following is a list of start−up options:

 

Buffer

Buffer options are to be placed in the [buffer] section.

These options are global to all buffers. For more granular filtering, use [[siteconf]].

Example:

[buffer]
# show images on all websites

images = true
# disable website CSS

styling = false
# Specify user styles.

user−style = '''
/* you can import external UA styles like this: */
@import 'user.css';
/* or just insert the style inline as follows. */
/* enforce the default text−decoration for links (i.e. underline). */
a[href] { text−decoration: revert !important }
@media (monochrome) { /* only in color−mode "monochrome" (or −M) */

/* disable UA style of bold font (no need for important here) */

a[href]:hover { font−weight: initial }

/* ...and italicize the font on hover instead.

* here we use important because we don't want websites to

* override the value. */

a[href]:hover { font−style: italic !important }

}
'''
# You *can* set scripting to true here, but I strongly recommend using
# [[siteconf]] to enable it on a per−site basis instead.

Following is a list of buffer options:

 

Search

Search options are to be placed in the [search] section.

Following is a list of search options:

Encoding

Encoding options are to be placed in the [encoding] section.

Following is a list of encoding options:

 

External

External options are to be placed in the [external] section.

Following is a list of external options:

Input

Input options are to be placed in the [input] section.

Examples:

[input]
vi−numeric−prefix = true

[page]
# Here, the arrow function will be called with the vi numbered prefix if
# one was input, and with no argument otherwise.
# The numeric prefix can never be zero, so it is safe to test for undefined
# using the ternary operator.
G = 'n => n ? pager.gotoLine(n) : pager.cursorLastLine()'

Network

Network options are to be placed in the [network] section.

Display

Display options are to be placed in the [display] section.

Following is a list of display options:

   

Status

Options concerning the status bar (last line on the screen) are to be placed in the [status] section.

Following is a list of status options:

Omnirule

The omni−bar (by default opened with C−l) can be used to perform searches using omni−rules. These are to be specified as sub−keys to table [omnirule]. (The sub−key itself is ignored; you can use anything as long it doesn’t conflict with other keys.)

Examples:

# Search using DuckDuckGo Lite.
# (This rule is included in the default config, although C−k invokes
# Brave search.)
[omnirule.ddg]
match = '^ddg:'
substitute−url = '(x) => "https://lite.duckduckgo.com/lite/?kp=−1&kd=−1&q=" + encodeURIComponent(x.split(":").slice(1).join(":"))'

# To use the above rule, open the URL bar with C−k, clear it with
# C−u, and type ddg:keyword.
# Alternatively, you can also redefine C−k like:
[page]
'C−k' = '() => pager.load("ddg:")'

# Search using Wikipedia, Firefox−style.
# The [[omnirule]] syntax introduces an anonymous omnirule; it is
# equivalent to the named one.
[[omnirule]]
match = '^@wikipedia'
substitute−url = '(x) => "https://en.wikipedia.org/wiki/Special:Search?search=" + encodeURIComponent(x.replace(/@wikipedia/, ""))'

As noted above, the default config includes some built−in rules, selected according to the maintainer’s preference and the minimum criterion that they must work without cookies and JavaScript. Currently, these are:

ddg: − DuckDuckGo Lite.

br: − Brave Search.

wk: − English Wikipedia.

wd: − English Wikitionary.

mo: − Mojeek.

Omnirule options:

Siteconf

Configuration options can be specified for individual sites. Entries are to be specified as sub−keys to table [siteconf]. (The sub−key itself is ignored; you can use anything as long it doesn’t conflict with other keys.)

Most siteconf options can also be specified globally; see the “overrides” field.

Examples:

# Enable cookies on the orange website for log−in.
[siteconf.hn]
url = 'https://news\.ycombinator\.com/.*'
cookie = true

# Redirect npr.org to text.npr.org.
[siteconf.npr]
host = '(www\.)?npr\.org'
rewrite−url = '''
(x) => {

x.host = "text.npr.org";

const s = x.pathname.split('/');

x.pathname = s.at(s.length > 2 ? −2 : 1);

/* No need to return; URL objects are passed by reference. */

}
'''

# Allow cookie sharing on *sr.ht domains.
[siteconf.sr−ht]
host = '(.*\.)?sr\.ht' # either 'something.sr.ht' or 'sr.ht'
cookie = true # enable cookies (read−only; use "save" to persist them)
share−cookie−jar = 'sr.ht' # use the cookie jar of 'sr.ht' for all matched hosts

# Use the "vector" skin on Wikipedia.
# The [[siteconf]] syntax introduces an anonymous siteconf; it is
# equivalent to the above ones.
[[siteconf]]
url = '^https?://[a−z]+\.wikipedia\.org/wiki/(?!.*useskin=.*)'
rewrite−url = 'x => x.searchParams.append("useskin", "vector")'

# Make imgur send us images.
[siteconf.imgur]
host = '(i\.)?imgur\.com'
default−headers = {

User−Agent = "Mozilla/5.0 chawan",

Accept = "*/*",

Accept−Encoding = "gzip, deflate",

Accept−Language = "en;q=1.0",

Pragma = "no−cache",

Cache−Control = "no−cache"

}

Siteconf options:

   

Keybindings

Keybindings are to be placed in these sections:

for pager interaction: [page]

for line editing: [line]

Keybindings are configured using the syntax

'<keybinding>' = '<action>'

Where <keybinding> is a combination of unicode characters with or without modifiers. Modifiers are the prefixes C− and M−, which add control or escape to the keybinding respectively (essentially making M− the same as C−[). Modifiers can be escaped with the \ sign.

<action> is either a command defined in the [cmd] section, or a JavaScript expression. Here we only describe the pre−defined actions in the default config; for a description of the API, please see:

The API documentation at cha−api(7).

Examples:

# show change URL when Control, Escape and j are pressed
'C−M−j' = 'load'

# go to the first line of the page when g is pressed twice without a preceding
# number, or to the line when a preceding number is given.

'gg' = 'gotoLineOrStart'

# JS functions and expressions are accepted too. Following replaces the
# default search engine with DuckDuckGo Lite.
# (See api.md for a list of available functions, and a discussion on how
# to add your own "namespaced" commands like above.)

'C−k' = '() => pager.load("ddg:")'

Pager actions

   

Buffer actions

Note: n in the following text refers to a number preceding the action. e.g. in 10gg, n = 10. If no preceding number is input, then it is left unspecified.

     

 

Line−editing actions

Note: to facilitate URL editing, the line editor has a different definition of what a word is than the pager. For the line editor, a word is either a sequence of alphanumeric characters, or any single non−alphanumeric character. (This means that e.g. https:// consists of four words: https, :, / and /.)

# Control+A moves the cursor to the beginning of the line.
'C−a' = 'line.begin'

# Escape+D deletes everything after the cursor until it reaches a word−breaking
# character.
'M−d' = 'line.killWord'

Appendix

Regex handling

Regular expressions are currently handled using the libregexp library from QuickJS. This means that all regular expressions work as in JavaScript.

There are two different modes of regex preprocessing in Chawan: “search” mode and “match” mode. Match mode is used for configurations (meaning in all values in this document described as “regex”). Search mode is used for the on−page search function (using searchForward/isearchForward etc.)

Match mode

Regular expressions are assumed to be exact matches, except when they start with a caret (^) sign or end with an unescaped dollar ($) sign.

In other words, the following transformations occur:

^abcd −> ^abcd (no change, only beginning is matched)
efgh$ −> efgh$ (no change, only end is matched)
^ijkl$ −> ^ijkl$ (no change, the entire line is matched)
mnop −> ^mnop$ (changed to exact match, the entire line is matched)

Match mode has no way to toggle JavaScript regex flags like i.

Search mode

For on−page search, the above transformations do not apply; the search /abcd searches for the string abcd inside all lines.

Search mode also has some other convenience transformations (these do not work in match mode):

The string \c (backslash + lower−case c) inside a search−mode regex enables case−insensitive matching.

Conversely, \C (backslash + capital C) disables case−insensitive matching. (Useful if you have ignore−case set to true, which is the default.)

\< and \> is converted to \b (as in vi, grep, etc.)

Like match mode, search mode operates on individual lines. This means that search patterns do not match text wrapped over multiple lines.

Path handling

Rules for path handling are similar to how the shell handles strings.

Tilde−expansion is used to determine the user’s home directory. So e.g. ~/whatever works.

Environment variables can be used like $ENV_VAR.

Relative paths are relative to the Chawan configuration directory (i.e. $CHA_DIR).

Some environment variables are also exported by Chawan:

$CHA_BIN_DIR: the directory which the cha binary resides in. Symbolic links are automatically resolved to determine this path.

$CHA_LIBEXEC_DIR: the directory for all executables Chawan uses for operation. By default, this is $CHA_BIN_DIR/../libexec/chawan.

$CHA_DIR: the configuration directory. (This can also be set by the user; see the top section for details.)

$CHA_DATA_DIR: if the configuration file uses XDG base directories, this is ${XDG_DATA_HOME:−$HOME/.local/share}/chawan. Otherwise, it is the same as $CHA_DIR.

Exception: if $CHA_DIR is set before cha is invoked, then $CHA_DATA_DIR is also read. This is to make nested invocations work in configurations with XDG basedirs.

Word types

Word−based pager commands can operate with different definitions of words. Currently, these are:

w3m words

vi words

Big words

w3m word

A w3m word is a sequence of alphanumeric characters. Symbols are treated in the same way as whitespace.

vi word

A vi word is a sequence of characters in the same character category. Currently, character categories are alphanumeric characters, symbols, han letters, hiragana, katakana, and hangul.

vi words may be separated by whitespace; however, vi words from separate categories do not have to be whitespace−separated. e.g. the following character sequence contains two words:

hello[]+{}@`!

Big word

A big word is a sequence of non−whitespace characters.

It is essentially the same as a w3m word, but with symbols being defined as non−whitespace.

See also

cha(1) cha−api(7)


Updated 2026-06-01 - jenkler.se | uex.se