batch-filecmdpowershell-corewindows-terminaloh-my-posh

Command segment in .omp.json Oh-my-posh theme


I've been modifying to my taste, the theme kali, from oh my posh.

I encountered the following problem.

I have this segment

{
  "type": "prompt",
  "alignment": "left",
  "segments": [
    {
      "type": "command",
      "style": "plain",
      "foreground": "#ffffff",
      "properties": {
        "shell": "cmd",
        "command": "cmd /C D:\\repos\\zsh-pwsh-wt\\windows-pws-posh\\center.bat"
      },
      "template": "{{ .Output }}"
    }
  ]
},

The point of that segment is to print a line as wide as the window above the main prompt. I do it through cmd because of compatibility issues with pwsh.

The file center.bat works perfectly by its own, prints the line as it should. The problem is that when I call that script file, the line it prints is shorter than the window width.

Here are examples:

Also, this example scenario:

enter image description here

Checking again, it always returns 120 when it runs from the template, despite the window size.

> {
  "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
  "blocks": [

    {
      "type": "prompt",
      "alignment": "right",
      "segments": [
        {
          "type": "command",
          "style": "plain",
          "foreground": "#ffffff",
          "properties": {
            "shell": "cmd",
            "command": "cmd /C D:\\repos\\zsh-pwsh-wt\\windows-pws-posh\\center.bat"
          },
          "template": "{{ .Output }}"
        }
      ]
    },
    

    {
      "alignment": "left",
      "segments": [
        {

          "properties": { "display_host": true },
          "style": "plain",
          "template": "\n<#ffffff>\u250c\u2500\u2500(</#ffffff><#00FF00>{{ .UserName }}</#00FF00>💀⌛<#ffffff><#ffffff>\u2500▶ </#ffffff><#ff0000>{{ .HostName }}</#ff0000><#ffffff><#ffffff>)</#ffffff></ffffff>",
          "type": "session"
        },
        {
          "foreground": "yellow",
          "properties": { "fetch_version": false, "fetch_virtual_env": true },
          "style": "plain",
          "template": "<#2fff00>[\ue235</#2fff00> {{ if .Error }}{{ .Error }}{{ else }}{{ if .Venv }}{{ .Venv }}{{ end }}{{ .Full }}{{ end }}<{{ if .Root }}#ffffff{{ else }}#00FF00{{ end }}>]</>",
          "type": "python"
        },

        {
          "properties": {
            "folder_separator_icon": "/",
            "style": "full"
          },
          "style": "plain",
          "template": "<#ffffff>──[</#ffffff><#00FF00>{{ .Path }}</#00FF00>",
          "type": "path"
        },
        {
          "type": "text",
          "template": "<#ffffff>]</#ffffff>"
        },
        {
          "type": "text",

          "template": "<#ffffff><d></d></#ffffff>"
        }
      ],
      "type": "prompt"
    },

    
    {
      "alignment": "right",
      "segments": [
        {
          "type": "git",
          "style": "plain",
          "properties": {
            "always_enabled": true,
            "branch_ahead_icon": "",
            "branch_behind_icon": "",
            "branch_gone_icon": "",
            "branch_icon": "",
            "branch_identical_icon": "",
            "cherry_pick_icon": "",
            "commit_icon": "",
            "fetch_status": true,
            "merge_icon": "",
            "rebase_icon": "",
            "revert_icon": "",
            "tag_icon": ""
          },
          "template": "<#2fff00>on─►</#2fff00><#ffffff> {{ .HEAD }}─►</#FF0000> {{ .Staging.String }}{{ if .Working.Changed }}<#FF0000> \u25cf─►</#FF0000> <#00FF00>{{ .Working.String }}{{ end }}</#00FF00>\n"
        }
        
      ],
      "type": "prompt"

    },
    

    {
      "alignment": "left",
      "segments": [
        {
          "type": "text",
          "template": "<#ffffff>\u2502</#ffffff> "
        }
        
      ],
      "type": "prompt"

    },



    {
      "alignment": "right",
      "newline": false,
      "segments": [
        {
          "type": "text",
          "style": "plain",
          "template": "<#ff0000>[</#ff0000>"
        },
        
        {
          "type": "time",
          "style": "plain",
          "properties": {
            "time_format": "<#ffffff>Monday, 02-Jan-06 15:04:05</#ffffff>"
          }
        },
        {
          "type": "text",
          "style": "plain",
          "template": "<#ff0000>]</#ff0000>"
        }
      ],
      "type": "prompt"
    }



    ,
    {
      "alignment": "left",
      "newline": true,
      "segments": [
        {
          "style": "plain",
          "template": "<#ffffff>\u2514\u2500▶<r> λ:</r> </#ffffff>",
          "type": "text"
        }
      ],
      "type": "prompt"
    }
  ],
  "version": 3
}

And the script:

@echo off
setlocal enabledelayedexpansion
set width=0

:: Get the current window width (number of columns)
for /f "tokens=2 delims=:" %%I in ('mode con ^| findstr "Columns"') do set width=%%I

:: Set the initial TEXT value to be repeated
set TEXT=─

:: Initialize an empty string to hold the repeated TEXT
set result=

:: Loop through the window width and append the TEXT to the result string
for /L %%i in (1,1,!width!) do (
    set result=!result!!TEXT!
)

:: Now echo the final string in one go
echo !result!
endlocal

Edit: I've been trying a lot,I tried passing the width as argument to the .bat, it works by itself, but in the template does not work, at least not when I pass an argument. So, I decide to do it through $Profile only, but only work when the prompt start:

oh-my-posh init pwsh --config 'D:\repos\zsh-pwsh-wt\windows-pws-posh\kalimod.omp.json' | Invoke-Expression
function prompt {
    $width = [console]::WindowWidth
    $result = "-" * $width
    [System.Environment]::SetEnvironmentVariable("PROMPT_LINE", $result, [System.EnvironmentVariableTarget]::Process)

    write-Host($result)
oh-my-posh init pwsh --config 'D:\repos\zsh-pwsh-wt\windows-pws-posh\kalimod.omp.json' | Invoke-Expression

    # Output the custom prompt (optional to display additional info)
    #return $line
}

# This line ensures the prompt is re-executed after each command is run
$ExecutionContext.InvokeCommand.CommandNotFoundAction = {
    # Force a prompt redraw after each command
    prompt

}


Solution

  • Resolved. Thank you @Compo for your observations. I discarded the .bat script approach. Final solution, I create an event in the .ps1 profile, that run every time a command (besides itself) runs, calculate the current window wide and save it in a global variable accessible from the omp.json theme file. Here is the code:

    oh-my-posh init pwsh --config 'D:\repos\zsh-pwsh-wt\windows-pws-posh\kalimod.omp.json' | Invoke-Expression
    $width = [console]::WindowWidth
        $result = "ˍ" * ($width-1)
        [System.Environment]::SetEnvironmentVariable("PROMPT_LINE", $result, [System.EnvironmentVariableTarget]::Process)
    Register-EngineEvent -SourceIdentifier PowerShell.OnIdle -Action {
        $width = [console]::WindowWidth
        $result = "ˍ" * ($width-1)
        [System.Environment]::SetEnvironmentVariable("PROMPT_LINE", $result, [System.EnvironmentVariableTarget]::Process)
        oh-my-posh init pwsh --config 'D:\repos\zsh-pwsh-wt\windows-pws-posh\kalimod.omp.json' | Invoke-Expression
    }

    And here is the block and how I call it in the theme:

       {
      "type": "prompt",
      "alignment": "left",
      "segments": [
        {
          "type": "command",
          "style": "plain",
          "foreground": "#ffffff",
          "properties": {
            "shell": "powershell",
            "command": "$env:PROMPT_LINE"
          }
        }
      ]
    },