feat(shell): support elvish

This commit is contained in:
Jan De Dobbeleer 2023-02-18 13:49:10 +01:00 committed by Jan De Dobbeleer
parent 3513597a6f
commit f84e7b209f
9 changed files with 101 additions and 3 deletions

View file

@ -250,6 +250,9 @@ func (w *Writer) FormatTitle(title string) string {
title = strings.NewReplacer("`", "\\`", `\`, `\\`).Replace(title)
case shell.ZSH:
title = strings.NewReplacer("`", "\\`", `%`, `%%`).Replace(title)
case shell.ELVISH:
// elvish doesn't support this
return ""
}
return fmt.Sprintf(w.title, title)
}

View file

@ -5,6 +5,7 @@ import (
"strings"
"github.com/jandedobbeleer/oh-my-posh/src/regex"
"github.com/jandedobbeleer/oh-my-posh/src/shell"
"github.com/mattn/go-runewidth"
)
@ -70,6 +71,11 @@ func (w *Writer) replaceHyperlink(text string) string {
linkText := results["TEXT"]
// this isn't supported for elvish
if w.shell == shell.ELVISH {
return strings.Replace(text, results["ALL"], linkText, 1)
}
// we only care about the length of the text part
w.length += runewidth.StringWidth(linkText)

View file

@ -30,6 +30,7 @@ See the documentation to initialize your shell: https://ohmyposh.dev/docs/instal
"cmd",
"nu",
"tcsh",
"elvish",
},
Args: NoArgsOrOneValidArg,
Run: func(cmd *cobra.Command, args []string) {

View file

@ -83,9 +83,15 @@ func (e *Engine) PrintPrimary() string {
}
func (e *Engine) printPWD() {
// only print when supported
if e.Env.Shell() == shell.ELVISH {
return
}
// only print when relevant
if len(e.Config.PWD) == 0 && !e.Config.OSC99 {
return
}
cwd := e.Env.Pwd()
// Backwards compatibility for deprecated OSC99
if e.Config.OSC99 {
@ -97,10 +103,12 @@ func (e *Engine) printPWD() {
Template: e.Config.PWD,
Env: e.Env,
}
pwdType, err := tmpl.Render()
if err != nil || len(pwdType) == 0 {
return
}
user := e.Env.User()
host, _ := e.Env.Host()
e.write(e.Writer.ConsolePwd(pwdType, user, host, cwd))

View file

@ -10,4 +10,5 @@ const (
NU = "nu"
GENERIC = "shell"
TCSH = "tcsh"
ELVISH = "elvish"
)

View file

@ -34,6 +34,9 @@ var nuInit string
//go:embed scripts/omp.tcsh
var tcshInit string
//go:embed scripts/omp.elv
var elvishInit string
const (
noExe = "echo \"Unable to find Oh My Posh executable\""
)
@ -156,7 +159,7 @@ func quoteNuStr(str string) string {
func Init(env platform.Environment) string {
shell := env.Flags().Shell
switch shell {
case PWSH, PWSH5:
case PWSH, PWSH5, ELVISH:
executable, err := getExecutablePath(env)
if err != nil {
return noExe
@ -168,8 +171,16 @@ func Init(env platform.Environment) string {
if env.Flags().Manual {
additionalParams += " --manual"
}
command := "(@(& %s init %s --config=%s --print%s) -join \"`n\") | Invoke-Expression"
return fmt.Sprintf(command, quotePwshStr(executable), shell, quotePwshStr(env.Flags().Config), additionalParams)
var command, config string
switch shell {
case PWSH, PWSH5:
command = "(@(& %s init %s --config=%s --print%s) -join \"`n\") | Invoke-Expression"
config = quotePwshStr(env.Flags().Config)
case ELVISH:
command = "eval (%s init %s --config=%s --print%s | slurp)"
config = quotePosixStr(env.Flags().Config)
}
return fmt.Sprintf(command, quotePwshStr(executable), shell, config, additionalParams)
case ZSH, BASH, FISH, CMD, TCSH:
return PrintInit(env)
case NU:
@ -225,6 +236,10 @@ func PrintInit(env platform.Environment) string {
executable = quotePosixStr(executable)
configFile = quotePosixStr(configFile)
script = tcshInit
case ELVISH:
executable = quotePosixStr(executable)
configFile = quotePosixStr(configFile)
script = elvishInit
default:
return fmt.Sprintf("echo \"No initialization script available for %s\"", shell)
}

32
src/shell/scripts/omp.elv Normal file
View file

@ -0,0 +1,32 @@
set-env POSH_PID (to-string (randint 10000000000000 10000000000000000))
set-env POSH_THEME '::CONFIG::'
set-env POWERLINE_COMMAND 'oh-my-posh'
set-env ELVISH_VERSION (elvish --version)
var error-code = 0
fn posh-after-command-hook {|m|
var error = $m[error]
if (is $error $nil) {
set error-code = 0
} else {
try {
set error-code = $error[reason][exit-status]
} catch {
# built-in commands don't have a status code.
set error-code = 1
}
}
}
set edit:after-command = [ $@edit:after-command $posh-after-command-hook~ ]
set edit:prompt = {
var cmd-duration = (printf "%.0f" (* $edit:command-duration 1000))
::OMP:: print primary --config=$E:POSH_THEME --shell=elvish --execution-time=$cmd-duration --error=$error-code --pwd=$pwd --shell-version=$E:ELVISH_VERSION
}
set edit:rprompt = {
var cmd-duration = (printf "%.0f" (* $edit:command-duration 1000))
::OMP:: print right --config=$E:POSH_THEME --shell=elvish --execution-time=$cmd-duration --error=$error-code --pwd=$pwd --shell-version=$E:ELVISH_VERSION
}

View file

@ -78,6 +78,7 @@ to reflect your use-case.
{ label: 'fish', value: 'fish', },
{ label: 'nu', value: 'nu', },
{ label: 'tcsh', value: 'tcsh', },
{ label: 'elvish', value: 'elvish', },
]
}>
<TabItem value="powershell">
@ -223,6 +224,21 @@ Once added, reload your profile for the changes to take effect.
exec tcsh
```
</TabItem>
<TabItem value="elvish">
Adjust or add the following line at the end of ~/.elvish/rc.elv:
```bash
eval (oh-my-posh init elvish --config ~/jandedobbeleer.omp.json)
```
Once added, reload your profile for the changes to take effect.
```bash
exec elvish
```
</TabItem>
</Tabs>

View file

@ -26,6 +26,7 @@ oh-my-posh get shell
{ label: 'fish', value: 'fish', },
{ label: 'nu', value: 'nu', },
{ label: 'tcsh', value: 'tcsh', },
{ label: 'elvish', value: 'elvish', },
]
}>
<TabItem value="powershell">
@ -202,6 +203,21 @@ Once added, reload your profile for the changes to take effect.
exec tcsh
```
</TabItem>
<TabItem value="elvish">
Add the following at the end of ~/.elvish/rc.elv:
```bash
eval (oh-my-posh init elvish)
```
Once added, reload your profile for the changes to take effect.
```bash
exec elvish
```
</TabItem>
</Tabs>