If else control flow operator

Since Kakoune doesn’t have if else control flow operator I’ve decided to add it myself:

try %{ require-module kak }
add-highlighter shared/kakrc/code/if_else regex \b(if|else)\b 0:keyword

define-command -docstring "if <condition> <expression> [else [if <condition>] <expression>]: if statement that accepts shell-valid condition string" \
if -params 2.. %{ evaluate-commands %sh{
    while [ true ]; do
        condition="[ $1 ]"
        if [ -n "$3" ] && [ "$3" != "else" ]; then
            printf "%s\n" "fail %{if: unknown operator '$3'}"
        elif [ $# -eq 3 ]; then
            printf "%s\n" "fail %{if: wrong argument count}"
        elif eval $condition; then
            [ -n "${2##*&*}" ] && arg="$2" || arg="$(printf '%s' "$2" | sed 's/&/&&/g')"
            printf "%s\n" "evaluate-commands %& $arg &"
        elif [ $# -eq 4 ]; then
            [ -n "${4##*&*}" ] && arg="$4" || arg="$(printf '%s' "$4" | sed 's/&/&&/g')"
            printf "%s\n" "evaluate-commands %& $arg &"
        elif [ $# -gt 4 ]; then
            if [ "$4" = "if" ]; then
                shift 4
                continue
            else
                printf "%s\n" "fail %{if: wrong argument count}"
            fi
        fi
        exit
    done
}}

Primary usage for me is to separate my desktop and mobile configurations, since I don’t want to use some plugins on mobile phone, like kak-lsp or tagbar.kak. Maybe someone will find it useful too.

4 Likes

You use Kakoune on your phone?!

This is cool, thanks for posting.
I guess it can simplify code a bit, if you only need to shell out for an if.
I wonder if there’s a way we could do it without a shell expansion. Maybe something using a series of try-catch blocks?

Figured I’d add the relevant issue for reference.
While I agree with keeping kakscript minimal, if this is something people are going to start using, IMO it should just be added to Kakoune.

@robertmeta Ya, it’s available on Termux!

Yeah, and not only Kakoune but also Emacs. Before using Kakoune there was Vim and NeoVim, and because I’ve used those on phone I’ve developed a snippet plugin for Vim because UltiSnips and SnipMate were really slow on the phone. plug.kak and fzf.kak, as well as my other plugins, were mostly developed on the phone. I waste two and a half hours each day in subway riding to work and back home so I’m trying to use most of this time for something useful (by making plugins, oh… what am I doing with my life… JK)

Small update.

I’ve added support for the else if construct. Now it is possible to chain if into else like so:

if %[ -n "$(command -v xsel)" ] %{
    # set xsel mappings
    map -docstring "cut to system clipboard" global user 'd' '|xsel -b -i<ret>'
    # ...
} else if %[ -n "$(command -v xclip)" ] %{
    # set xclip mappings...
} else %{
    echo -debug "neither xsel nor xclip is available"
}

I’ve updated the code in the main comment