feat(image): add -o, --output flag

This commit is contained in:
L. Yeung 2022-05-06 00:06:31 +08:00 committed by Jan De Dobbeleer
parent 217b3c73c4
commit 2e5fa3f1d2
5 changed files with 51 additions and 16 deletions

View file

@ -13,13 +13,13 @@ Depending on your config, you might have to tweak the output a little bit.
::: :::
The oh-my-posh executable has the `config export image` command to export your current theme configuration The oh-my-posh executable has the `config export image` command to export your current theme configuration
to the current directory. to an image file (.png).
```powershell ```powershell
oh-my-posh config export image --cursor-padding 50 oh-my-posh config export image --cursor-padding 50
``` ```
There are a couple of additional switches you can use to tweak the image rendering: There are a couple of additional flags you can use to tweak the image rendering:
- `--cursor-padding`: spaces to add after the cursor indication (`_`) - `--cursor-padding`: spaces to add after the cursor indication (`_`)
- `--rprompt-offset`: spaces to add **before** a block that's right aligned - `--rprompt-offset`: spaces to add **before** a block that's right aligned

View file

@ -66,8 +66,8 @@ func cleanOutputPath(path string, env environment.Environment) string {
path = filepath.Join(env.Home(), path) path = filepath.Join(env.Home(), path)
} }
if !filepath.IsAbs(path) { if !filepath.IsAbs(path) {
if absConfigFile, err := filepath.Abs(path); err == nil { if absPath, err := filepath.Abs(path); err == nil {
path = absConfigFile path = absPath
} }
} }
return filepath.Clean(path) return filepath.Clean(path)

View file

@ -16,6 +16,7 @@ var (
cursorPadding int cursorPadding int
rPromptOffset int rPromptOffset int
bgColor string bgColor string
outputImage string
) )
// imageCmd represents the image command // imageCmd represents the image command
@ -37,6 +38,10 @@ Example usage:
Exports the config to an image file called myconfig.png in the current working directory. Exports the config to an image file called myconfig.png in the current working directory.
> oh-my-posh config export image --config ~/myconfig.omp.json --output ~/mytheme.png
Exports the config to an image file ~/mytheme.png.
> oh-my-posh config export image --config ~/myconfig.omp.json --author "John Doe" > oh-my-posh config export image --config ~/myconfig.omp.json --author "John Doe"
Exports the config to an image file using customized output options.`, Exports the config to an image file using customized output options.`,
@ -81,6 +86,9 @@ Exports the config to an image file using customized output options.`,
BgColor: bgColor, BgColor: bgColor,
Ansi: ansi, Ansi: ansi,
} }
if outputImage != "" {
imageCreator.Path = cleanOutputPath(outputImage, env)
}
imageCreator.Init(env.Flags().Config) imageCreator.Init(env.Flags().Config)
err := imageCreator.SavePNG() err := imageCreator.SavePNG()
if err != nil { if err != nil {
@ -94,5 +102,6 @@ func init() { // nolint:gochecknoinits
imageCmd.Flags().StringVar(&bgColor, "background-color", "", "image background color") imageCmd.Flags().StringVar(&bgColor, "background-color", "", "image background color")
imageCmd.Flags().IntVar(&cursorPadding, "cursor-padding", 0, "prompt cursor padding") imageCmd.Flags().IntVar(&cursorPadding, "cursor-padding", 0, "prompt cursor padding")
imageCmd.Flags().IntVar(&rPromptOffset, "rprompt-offset", 0, "right prompt offset") imageCmd.Flags().IntVar(&rPromptOffset, "rprompt-offset", 0, "right prompt offset")
imageCmd.Flags().StringVarP(&outputImage, "output", "o", "", "image file (.png) to export to")
exportCmd.AddCommand(imageCmd) exportCmd.AddCommand(imageCmd)
} }

View file

@ -105,7 +105,7 @@ type ImageRenderer struct {
BgColor string BgColor string
Ansi *color.Ansi Ansi *color.Ansi
path string Path string
factor float64 factor float64
@ -136,8 +136,10 @@ type ImageRenderer struct {
} }
func (ir *ImageRenderer) Init(config string) { func (ir *ImageRenderer) Init(config string) {
match := regex.FindNamedRegexMatch(`.*(\/|\\)(?P<STR>.+).omp.(json|yaml|toml)`, config) if ir.Path == "" {
ir.path = fmt.Sprintf("%s.png", match[str]) match := regex.FindNamedRegexMatch(`.*(\/|\\)(?P<STR>.+)\.(json|yaml|yml|toml)`, config)
ir.Path = fmt.Sprintf("%s.png", strings.TrimSuffix(match[str], ".omp"))
}
f := 2.0 f := 2.0
@ -446,7 +448,7 @@ func (ir *ImageRenderer) SavePNG() error {
x += w x += w
} }
return dc.SavePNG(ir.path) return dc.SavePNG(ir.Path)
} }
func (ir *ImageRenderer) shouldPrint() bool { func (ir *ImageRenderer) shouldPrint() bool {

View file

@ -5,16 +5,31 @@ import (
"oh-my-posh/color" "oh-my-posh/color"
"oh-my-posh/shell" "oh-my-posh/shell"
"os" "os"
"path/filepath"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func runImageTest(content string) error { var cases = []struct {
Case string
Config string
}{
{Case: ".omp.json suffix", Config: "~/jandedobbeleer.omp.json"},
{Case: ".omp.yaml suffix", Config: "~/jandedobbeleer.omp.yaml"},
{Case: ".omp.yml suffix", Config: "~/jandedobbeleer.omp.yml"},
{Case: ".omp.toml suffix", Config: "~/jandedobbeleer.omp.toml"},
{Case: ".json suffix", Config: "~/jandedobbeleer.json"},
{Case: ".yaml suffix", Config: "~/jandedobbeleer.yaml"},
{Case: ".yml suffix", Config: "~/jandedobbeleer.yml"},
{Case: ".toml suffix", Config: "~/jandedobbeleer.toml"},
}
func runImageTest(config, content string) (string, error) {
poshImagePath := "jandedobbeleer.png" poshImagePath := "jandedobbeleer.png"
file, err := ioutil.TempFile("", poshImagePath) file, err := ioutil.TempFile("", poshImagePath)
if err != nil { if err != nil {
return err return "", err
} }
defer os.Remove(file.Name()) defer os.Remove(file.Name())
ansi := &color.Ansi{} ansi := &color.Ansi{}
@ -23,18 +38,27 @@ func runImageTest(content string) error {
AnsiString: content, AnsiString: content,
Ansi: ansi, Ansi: ansi,
} }
image.Init("~/jandedobbeleer.omp.json") image.Init(config)
err = image.SavePNG() err = image.SavePNG()
return err if err == nil {
os.Remove(image.Path)
}
return filepath.Base(image.Path), err
} }
func TestStringImageFileWithText(t *testing.T) { func TestStringImageFileWithText(t *testing.T) {
err := runImageTest("foobar") for _, tc := range cases {
assert.NoError(t, err) filename, err := runImageTest(tc.Config, "foobar")
assert.Equal(t, "jandedobbeleer.png", filename, tc.Case)
assert.NoError(t, err)
}
} }
func TestStringImageFileWithANSI(t *testing.T) { func TestStringImageFileWithANSI(t *testing.T) {
prompt := ` jan  ` prompt := ` jan  `
err := runImageTest(prompt) for _, tc := range cases {
assert.NoError(t, err) filename, err := runImageTest(tc.Config, prompt)
assert.Equal(t, "jandedobbeleer.png", filename, tc.Case)
assert.NoError(t, err)
}
} }