mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-11-09 20:44:03 -08:00
fix(cli): correct execution logic and improve messages
This commit is contained in:
parent
48f633e0cb
commit
e28d91b854
|
@ -3,7 +3,6 @@ package cli
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
|
@ -50,7 +49,7 @@ You can do the following:
|
|||
clear(env.CachePath())
|
||||
case "edit":
|
||||
cacheFilePath := filepath.Join(env.CachePath(), cache.FileName)
|
||||
editFileWithEditor(cacheFilePath)
|
||||
os.Exit(editFileWithEditor(cacheFilePath))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -59,25 +58,6 @@ func init() {
|
|||
RootCmd.AddCommand(getCache)
|
||||
}
|
||||
|
||||
func editFileWithEditor(file string) {
|
||||
editor := os.Getenv("EDITOR")
|
||||
|
||||
var args []string
|
||||
if strings.Contains(editor, " ") {
|
||||
splitted := strings.Split(editor, " ")
|
||||
editor = splitted[0]
|
||||
args = splitted[1:]
|
||||
}
|
||||
|
||||
args = append(args, file)
|
||||
cmd := exec.Command(editor, args...)
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func clear(cachePath string) {
|
||||
// get all files in the cache directory that start with omp.cache and delete them
|
||||
files, err := os.ReadDir(cachePath)
|
||||
|
|
|
@ -5,16 +5,18 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// configCmd represents the config command
|
||||
var configCmd = &cobra.Command{
|
||||
Use: "config [export|migrate|edit]",
|
||||
Use: "config edit",
|
||||
Short: "Interact with the config",
|
||||
Long: `Interact with the config.
|
||||
|
||||
You can export, migrate or edit the config.`,
|
||||
You can export, migrate or edit the config (via the editor specified in the environment variable "EDITOR").`,
|
||||
ValidArgs: []string{
|
||||
"export",
|
||||
"migrate",
|
||||
|
@ -29,7 +31,13 @@ You can export, migrate or edit the config.`,
|
|||
}
|
||||
switch args[0] {
|
||||
case "edit":
|
||||
editFileWithEditor(os.Getenv("POSH_THEME"))
|
||||
env := &runtime.Terminal{
|
||||
CmdFlags: &runtime.Flags{
|
||||
Config: configFlag,
|
||||
},
|
||||
}
|
||||
env.ResolveConfigPath()
|
||||
os.Exit(editFileWithEditor(env.CmdFlags.Config))
|
||||
case "get":
|
||||
// only here for backwards compatibility
|
||||
fmt.Print(time.Now().UnixNano() / 1000000)
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/config"
|
||||
|
@ -13,9 +12,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
output string
|
||||
)
|
||||
var output string
|
||||
|
||||
// exportCmd represents the export command
|
||||
var exportCmd = &cobra.Command{
|
||||
|
@ -27,15 +24,21 @@ You can choose to print the output to stdout, or export your config in the forma
|
|||
|
||||
Example usage:
|
||||
|
||||
> oh-my-posh config export --config ~/myconfig.omp.json
|
||||
|
||||
Exports the ~/myconfig.omp.json config file and prints the result to stdout.
|
||||
|
||||
> oh-my-posh config export --config ~/myconfig.omp.json --format toml
|
||||
|
||||
Exports the ~/myconfig.omp.json config file to toml and prints the result to stdout.`,
|
||||
Exports the config file "~/myconfig.omp.json" in TOML format and prints the result to stdout.
|
||||
|
||||
> oh-my-posh config export --output ~/new_config.omp.json
|
||||
|
||||
Exports the current config to "~/new_config.omp.json" (in JSON format).`,
|
||||
Args: cobra.NoArgs,
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
if len(output) == 0 && len(format) == 0 {
|
||||
// usage error
|
||||
fmt.Println("neither output path nor export format is specified")
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
env := &runtime.Terminal{
|
||||
CmdFlags: &runtime.Flags{
|
||||
Config: configFlag,
|
||||
|
@ -45,15 +48,25 @@ Exports the ~/myconfig.omp.json config file to toml and prints the result to std
|
|||
defer env.Close()
|
||||
cfg := config.Load(env)
|
||||
|
||||
if len(output) == 0 && len(format) == 0 {
|
||||
// usage error
|
||||
os.Exit(2)
|
||||
validateExportFormat := func() {
|
||||
format = strings.ToLower(format)
|
||||
switch format {
|
||||
case "json", "jsonc":
|
||||
format = config.JSON
|
||||
case "toml", "tml":
|
||||
format = config.TOML
|
||||
case "yaml", "yml":
|
||||
format = config.YAML
|
||||
default:
|
||||
formats := []string{"json", "jsonc", "toml", "tml", "yaml", "yml"}
|
||||
// usage error
|
||||
fmt.Printf("export format must be one of these: %s\n", strings.Join(formats, ", "))
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
||||
|
||||
formats := []string{"json", "jsonc", "toml", "tml", "yaml", "yml"}
|
||||
if len(format) != 0 && !slices.Contains(formats, format) {
|
||||
// usage error
|
||||
os.Exit(2)
|
||||
if len(format) != 0 {
|
||||
validateExportFormat()
|
||||
}
|
||||
|
||||
if len(output) == 0 {
|
||||
|
@ -65,18 +78,7 @@ Exports the ~/myconfig.omp.json config file to toml and prints the result to std
|
|||
|
||||
if len(format) == 0 {
|
||||
format = strings.TrimPrefix(filepath.Ext(output), ".")
|
||||
}
|
||||
|
||||
switch format {
|
||||
case "json", "jsonc":
|
||||
format = config.JSON
|
||||
case "toml", "tml":
|
||||
format = config.TOML
|
||||
case "yaml", "yml":
|
||||
format = config.YAML
|
||||
default:
|
||||
// data error
|
||||
os.Exit(65)
|
||||
validateExportFormat()
|
||||
}
|
||||
|
||||
cfg.Write(format)
|
||||
|
@ -84,10 +86,7 @@ Exports the ~/myconfig.omp.json config file to toml and prints the result to std
|
|||
}
|
||||
|
||||
func cleanOutputPath(path string, env runtime.Environment) string {
|
||||
if strings.HasPrefix(path, "~") {
|
||||
path = strings.TrimPrefix(path, "~")
|
||||
path = filepath.Join(env.Home(), path)
|
||||
}
|
||||
path = runtime.ReplaceTildePrefixWithHomeDir(env, path)
|
||||
|
||||
if !filepath.IsAbs(path) {
|
||||
if absPath, err := filepath.Abs(path); err == nil {
|
||||
|
|
34
src/cli/edit.go
Normal file
34
src/cli/edit.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func editFileWithEditor(file string) int {
|
||||
editor := strings.TrimSpace(os.Getenv("EDITOR"))
|
||||
if len(editor) == 0 {
|
||||
fmt.Println(`no editor specified in the environment variable "EDITOR"`)
|
||||
return 1
|
||||
}
|
||||
|
||||
var args []string
|
||||
if strings.Contains(editor, " ") {
|
||||
strs := strings.Split(editor, " ")
|
||||
editor = strs[0]
|
||||
args = strs[1:]
|
||||
}
|
||||
|
||||
args = append(args, file)
|
||||
cmd := exec.Command(editor, args...)
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
return cmd.ProcessState.ExitCode()
|
||||
}
|
|
@ -66,7 +66,6 @@ var printCmd = &cobra.Command{
|
|||
Plain: plain,
|
||||
Primary: args[0] == "primary",
|
||||
Cleared: cleared,
|
||||
Cached: cached,
|
||||
NoExitCode: noStatus,
|
||||
Column: column,
|
||||
JobCount: jobCount,
|
||||
|
|
|
@ -98,7 +98,6 @@ type Flags struct {
|
|||
HasTransient bool
|
||||
PromptCount int
|
||||
Cleared bool
|
||||
Cached bool
|
||||
NoExitCode bool
|
||||
Column int
|
||||
JobCount int
|
||||
|
|
|
@ -74,7 +74,7 @@ func (term *Terminal) Init() {
|
|||
term.deviceCache = initCache(cache.FileName)
|
||||
term.sessionCache = initCache(cache.SessionFileName)
|
||||
|
||||
term.resolveConfigPath()
|
||||
term.ResolveConfigPath()
|
||||
|
||||
term.cmdCache = &cache.Command{
|
||||
Commands: maps.NewConcurrent(),
|
||||
|
@ -82,12 +82,10 @@ func (term *Terminal) Init() {
|
|||
|
||||
term.tmplCache = &cache.Template{}
|
||||
|
||||
if !term.CmdFlags.Cached {
|
||||
term.SetPromptCount()
|
||||
}
|
||||
term.SetPromptCount()
|
||||
}
|
||||
|
||||
func (term *Terminal) resolveConfigPath() {
|
||||
func (term *Terminal) ResolveConfigPath() {
|
||||
defer term.Trace(time.Now())
|
||||
|
||||
// if the config flag is set, we'll use that over POSH_THEME
|
||||
|
@ -129,11 +127,7 @@ func (term *Terminal) resolveConfigPath() {
|
|||
return
|
||||
}
|
||||
|
||||
configFile := term.CmdFlags.Config
|
||||
if strings.HasPrefix(configFile, "~") {
|
||||
configFile = strings.TrimPrefix(configFile, "~")
|
||||
configFile = filepath.Join(term.Home(), configFile)
|
||||
}
|
||||
configFile := ReplaceTildePrefixWithHomeDir(term, term.CmdFlags.Config)
|
||||
|
||||
abs, err := filepath.Abs(configFile)
|
||||
if err != nil {
|
||||
|
@ -726,11 +720,14 @@ func dirMatchesOneOf(dir, home, goos string, regexes []string) bool {
|
|||
}
|
||||
|
||||
for _, element := range regexes {
|
||||
normalizedElement := strings.ReplaceAll(element, "\\\\", "/")
|
||||
if strings.HasPrefix(normalizedElement, "~") {
|
||||
normalizedElement = strings.Replace(normalizedElement, "~", home, 1)
|
||||
normalized := strings.ReplaceAll(element, "\\\\", "/")
|
||||
if strings.HasPrefix(normalized, "~") {
|
||||
rem := normalized[1:]
|
||||
if len(rem) == 0 || rem[0] == '/' {
|
||||
normalized = home + rem
|
||||
}
|
||||
}
|
||||
pattern := fmt.Sprintf("^%s$", normalizedElement)
|
||||
pattern := fmt.Sprintf("^%s$", normalized)
|
||||
if goos == WINDOWS || goos == DARWIN {
|
||||
pattern = "(?i)" + pattern
|
||||
}
|
||||
|
@ -843,9 +840,19 @@ func Base(env Environment, path string) string {
|
|||
return path
|
||||
}
|
||||
|
||||
func ReplaceTildePrefixWithHomeDir(env Environment, path string) string {
|
||||
if !strings.HasPrefix(path, "~") {
|
||||
return path
|
||||
}
|
||||
rem := path[1:]
|
||||
if len(rem) == 0 || IsPathSeparator(env, rem[0]) {
|
||||
return env.Home() + rem
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func ReplaceHomeDirPrefixWithTilde(env Environment, path string) string {
|
||||
home := env.Home()
|
||||
// match Home directory exactly
|
||||
if !strings.HasPrefix(path, home) {
|
||||
return path
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ will not be rendered when in one of the excluded locations.
|
|||
```
|
||||
|
||||
The strings specified in these properties are evaluated as [regular expressions][regex]. You
|
||||
can use any valid regular expression construct, but the regular expression must match the entire directory
|
||||
can use any valid regular expression construct, but the regular expression must match the **ENTIRE** directory
|
||||
name. The following will match `/Users/posh/Projects/Foo` but not `/home/Users/posh/Projects/Foo`.
|
||||
|
||||
```json
|
||||
|
@ -165,8 +165,8 @@ You can also combine these properties:
|
|||
|
||||
- Oh My Posh will accept both `/` and `\` as path separators for a folder and will match regardless of which
|
||||
is used by the current operating system.
|
||||
- Because the strings are evaluated as regular expressions, if you want to use a `\` in a Windows
|
||||
directory name, you need to specify it as `\\\\`.
|
||||
- Because the strings are evaluated as regular expressions, if you want to use a backslash (`\`) in a Windows
|
||||
directory name, you need to specify it as double backslashes, and if using JSON format you should escape it as `\\\\`.
|
||||
- The character `~` at the start of a specified folder will match the user's home directory.
|
||||
- The comparison is case-insensitive on Windows and macOS, but case-sensitive on other operating systems.
|
||||
|
||||
|
|
Loading…
Reference in a new issue