Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add settings to set custom function to format prompt #3922

Merged
merged 1 commit into from
Oct 25, 2020

Conversation

jnoortheen
Copy link
Member

Now the users can format the prompt as they like.

@jnoortheen
Copy link
Member Author

here is a script to implement powerline like prompt

import os
from typing import NamedTuple, List
import builtins
from xonsh.prompt.base import ParsedTokens, _ParsedToken

GRAY = '#273746'
BLUE = '#004C99'
PROMPT_FIELD_COLORS = {
    "cwd": ("WHITE", "CYAN"),
    "gitstatus": ("WHITE", "BLACK"),
    "ret_code": ("WHITE", "RED"),
    "full_env_name": ("white", "green"),
    "hostname": ("white", BLUE),
    "localtime": ("#DAF7A6", "black")
}
POWERLINE_MODE = 'flame'

modes = {
    "powerline": "",
    "round": "",
    "down": "",
    "up": "",
    "flame": "",
    "squares": "",
    "ruiny": "",
    "lego": "",
}


class Section(NamedTuple):
    line: str
    fg: str = ''
    bg: str = ''


def prompt_builder(tokens: List[Section], right=False):
    size = len(tokens)
    prompt = []
    SEP, THIN, PL_RSEP, _ = modes[POWERLINE_MODE]
    for i, sec in enumerate(tokens):
        last = (i == size - 1)
        first = (i == 0)

        if right:
            prompt.append('{%s}%s{BACKGROUND_%s}{%s}%s' % (sec.bg, PL_RSEP, sec.bg, sec.fg, sec.line))
        else:
            if first:
                if sec.bg:
                    prompt.append('{BACKGROUND_%s}' % sec.bg)
            if sec.fg:
                prompt.append('{%s}' % sec.fg)

            prompt.append(sec.line)
            if last:
                prompt.append('{RESET}')
                if sec.bg:
                    prompt.append('{%s}' % sec.bg)
                prompt.append('%s{RESET}' % SEP)
            else:
                if tokens[i + 1].bg:
                    prompt.append('{BACKGROUND_%s}' % tokens[i + 1].bg)
                if sec.bg:
                    prompt.append('{%s}' % sec.bg)
                prompt.append(SEP)
    return ''.join(prompt)


def create_sections(tokens: List[_ParsedToken]):
    for tok in tokens:
        if not tok.value:  # skip empty strings
            continue
        args = PROMPT_FIELD_COLORS.get(
            tok.field,
            (
                'white',
                GRAY
            ))
        yield Section(tok.value, *[a.upper() for a in args])


def split_by_lines(tokens: List[_ParsedToken]):
    line = []
    for tok in tokens:
        if tok.value == os.linesep:
            yield list(create_sections(line))
            line.clear()
        else:
            line.append(tok)
    yield list(create_sections(line))


def process_prompt_tokens(container: ParsedTokens) -> str:
    prompt = builtins.__xonsh__.env['PROMPT']
    rprompt = builtins.__xonsh__.env["RIGHT_PROMPT"]
    if container.template in {prompt, rprompt}:
        # it is $PROMPT
        is_right = container.template == rprompt
        return os.linesep.join([
            prompt_builder(line, right=is_right) for line in split_by_lines(container.tokens)
        ])

    # for title
    return "".join([c.value for c in container.tokens])

# $PROMPT_TOKENS_FORMATTER = process_prompt_tokens

and sample prompt
image

@jnoortheen jnoortheen force-pushed the feat-prompt-formatter branch 2 times, most recently from fd44ee4 to 994d92a Compare October 23, 2020 12:30
xonsh/environ.py Outdated Show resolved Hide resolved
xonsh/environ.py Outdated Show resolved Hide resolved
xonsh/prompt/base.py Outdated Show resolved Hide resolved
xonsh/prompt/base.py Outdated Show resolved Hide resolved
@scopatz
Copy link
Member

scopatz commented Oct 23, 2020

Thanks for putting this in @jnoortheen! The code looks good to me, other than the logging issue.

@jnoortheen jnoortheen force-pushed the feat-prompt-formatter branch 2 times, most recently from 911e37e to 4eacf82 Compare October 24, 2020 08:50
xonsh/ptk_shell/updator.py Outdated Show resolved Hide resolved
xonsh/prompt/base.py Outdated Show resolved Hide resolved
@scopatz scopatz merged commit d0a832c into xonsh:master Oct 25, 2020
@scopatz
Copy link
Member

scopatz commented Oct 25, 2020

Thanks!

@jnoortheen jnoortheen deleted the feat-prompt-formatter branch November 9, 2020 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants