NiShiKi : Customize Your NiShiKi

Customize your NiShiKi as you like!

This section provides examples of customization on your NiShiKi. You can add and modify prompt, key bindings, and completions without touching NiShiKi source code.

Customize Through Config File

Create your config file

At first, you need to create your config file if you haven't created yet. You can write a config file from scratch, but it's better to start from this config.py file. Please download it and place on ~/.config/nishiki/config.py.

mkdir -p ~/.config/nishiki
mv DOWNLOAD_DIRECTORY/config.py ~/.config/nishiki/config.py

Configure prompt

You can customize your prompt by defining a function get_ps0, get_ps1, and get_ps2 that return a propmt string. The prompt string returned by get_ps1 and get_ps2 corresponds to PS1 and PS2 of Bash respectively. The string of get_ps0 will be displayed before the editing line:

<- get_ps0 ----------------------------------------------------->
<- get_ps1 -> <- user input ------------------------------------>
<- get_ps2 -> <- user input ------------------------------------>
...

The default definition of get_ps* is the following:

def get_ps0() -> str:
    """
    Returns the line before the prompt.
    """
    # Get the date and time string.
    date, time = str(datetime.datetime.now()).split()

    # Get the current directory.
    try   : cwd = os.getcwd().replace(os.getenv("HOME"), "~")
    except: cwd = "???"

    # Get the width of the terminal.
    width = nishiki.get("width")

    # Get the git branch info.
    git_info = get_git_branch_info()

    # Create the left side of the prompt string.
    prompt  = "\x1b[31m{user} \x1b[0m: ".format(user=os.getenv("USER"))
    prompt += "\x1b[32m{name} \x1b[0m: ".format(name=os.getenv("NAME"))
    prompt += "\x1b[33m{date} \x1b[0m: ".format(date=date)
    prompt += "\x1b[34m{time} \x1b[0m: ".format(time=time)
    prompt += "\x1b[35m{cwd}\x1b[0m".format(cwd=cwd)

    # Create the right side of the prompt string.
    prompt += " " * (width - strwidth(prompt) - strwidth(git_info) - 1)
    prompt += git_info

    return prompt


def get_ps1() -> str:
    """
    Returns the first prompt.
    """
    return "=>> "


def get_ps2() -> str:
    """
    Returns the second prompt.
    """
    return ".. "


#-------------------------------------------------------------------------------
# Utility functions
#-------------------------------------------------------------------------------

def get_git_branch_info() -> str:
    """
    Get git branch and status information and return as a colored string.
    """
    # Get git branch and status information.
    branch = nishiki.check_output("git rev-parse --abbrev-ref HEAD").strip()
    status = nishiki.check_output("git status --porcelain").strip()

    if ((len(branch) > 0) and (len(status) > 0)):
        return ("\x1b[33m" + branch + "!\x1b[m");
    elif len(branch) > 0:
        return ("\x1b[32m" + branch +  "\x1b[m");
    return branch;


def strwidth(text: str) -> int:
    """
    Compute the width of the given string.

    Args:
        text (str): Target string.

    Returns:
        (int): Width of the string.
    """
    def get_width_char(c: str) -> int:
        """
        Get the width of a unicode character.
        """
        if               ord(c) <= 0x0000FF: return 1
        elif 0xEFBDB1 <= ord(c) <= 0xEFBE9F: return 1
        else                               : return 2

    # Ignroe ANSI SGR.
    text = re.sub("\x1b\\[[0-9]*m", "", text)

    return sum(map(get_width_char, text))

Add new key binding

You can customize the keybind of NiShiKi by the keybinds variable of the config file. The following is the format of the items in the keybinds variable:

keybinds: list = [
    ["<keybind>", "!<command_type>[<option>] <command>"],
    ...,
]

where <keybind> is a keybind to be assigned, <command_type> is a command type spacifier, <option> is optional characters for command type, and <command> is a command to ce called. The <command_type> must be either int (internal) or ext (external). The details of each command type are as follows.

command_type: int

The internal command calls NiShiKi-internal functions (i.e. functions embedded in NiShiKi). It has three command contents:

This sample config file sets keybinds of them to Ctrl-F, Ctrl-H, and Ctrl-P respectively. See the sample config file.

command_type: ext

The external command calls an external command, for example xclip, and inserts the command results into your editing line if you want. The external command types have several specifiers, i, l and r etc. The specifiers are declared like ext[il] which means the external command with i and l specifiers. The following is the meaning of each specifier.

Note that the simple command type "ext" is equivalent to ext[ilr]. Whitespace is necessary after the internal/external specifier.

The following variables are available for external commands:

Add new completion

You can customize the command completions of NiShiKi by the completions variable of the config file. The following is the format of the items in the completions variable:

completions: list = [
    [[PATTERN, ...], COMPLETION_TYPE, EXTRA_STRING],
    ...,
]

where PATTERN is a list of strings, COMPLETION_TYPE is a completion type, and EXTRA_STRING is additional string for completion. If user input matches to the PATTERN, the corresponding completion will be applied. There are several types of completion, "command", "filepath", "option", "preview", "shell", and "subcmd". The following is the short explanation of each completion type.