mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-25 19:14:50 -08:00
Merge branch 'main' into vite
This commit is contained in:
commit
dd17e63dba
|
@ -14,21 +14,22 @@ func editFileWithEditor(file string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
var args []string
|
||||
if strings.Contains(editor, " ") {
|
||||
strs := strings.Split(editor, " ")
|
||||
editor = strs[0]
|
||||
args = strs[1:]
|
||||
}
|
||||
editor = strings.TrimSpace(editor)
|
||||
args := strings.Split(editor, " ")
|
||||
|
||||
editor = args[0]
|
||||
args = append(args[1:], file)
|
||||
|
||||
args = append(args, file)
|
||||
cmd := exec.Command(editor, args...)
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
return cmd.ProcessState.ExitCode()
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -72,14 +72,13 @@ const (
|
|||
)
|
||||
|
||||
type main struct {
|
||||
err error
|
||||
list *list.Model
|
||||
font string
|
||||
zipFolder string
|
||||
families []string
|
||||
spinner spinner.Model
|
||||
state state
|
||||
system bool
|
||||
err error
|
||||
list *list.Model
|
||||
Asset
|
||||
families []string
|
||||
spinner spinner.Model
|
||||
state state
|
||||
system bool
|
||||
}
|
||||
|
||||
func (m *main) buildFontList(nerdFonts []*Asset) {
|
||||
|
@ -122,7 +121,7 @@ func downloadFontZip(location string) {
|
|||
}
|
||||
|
||||
func installLocalFontZIP(m *main) {
|
||||
data, err := os.ReadFile(m.font)
|
||||
data, err := os.ReadFile(m.URL)
|
||||
if err != nil {
|
||||
program.Send(errMsg(err))
|
||||
return
|
||||
|
@ -143,28 +142,48 @@ func installFontZIP(zipFile []byte, m *main) {
|
|||
|
||||
func (m *main) Init() tea.Cmd {
|
||||
isLocalZipFile := func() bool {
|
||||
return !strings.HasPrefix(m.font, "https") && strings.HasSuffix(m.font, ".zip")
|
||||
return !strings.HasPrefix(m.URL, "https") && strings.HasSuffix(m.URL, ".zip")
|
||||
}
|
||||
|
||||
if len(m.font) != 0 && !isLocalZipFile() {
|
||||
resolveFontZipURL := func() error {
|
||||
if strings.HasPrefix(m.URL, "https") {
|
||||
return nil
|
||||
}
|
||||
|
||||
fonts, err := Fonts()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var fontAsset *Asset
|
||||
for _, font := range fonts {
|
||||
if m.URL != font.Name {
|
||||
continue
|
||||
}
|
||||
|
||||
fontAsset = font
|
||||
break
|
||||
}
|
||||
|
||||
if fontAsset == nil {
|
||||
return fmt.Errorf("no matching font found")
|
||||
}
|
||||
|
||||
m.Asset = *fontAsset
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(m.URL) != 0 && !isLocalZipFile() {
|
||||
m.state = downloadFont
|
||||
|
||||
if !strings.HasPrefix(m.font, "https") {
|
||||
if m.font == CascadiaCodeMS {
|
||||
cascadia, err := CascadiaCode()
|
||||
if err != nil {
|
||||
m.err = err
|
||||
return tea.Quit
|
||||
}
|
||||
|
||||
m.font = cascadia.URL
|
||||
} else {
|
||||
m.font = fmt.Sprintf("https://github.com/ryanoasis/nerd-fonts/releases/latest/download/%s.zip", m.font)
|
||||
}
|
||||
if err := resolveFontZipURL(); err != nil {
|
||||
m.err = err
|
||||
return tea.Quit
|
||||
}
|
||||
|
||||
defer func() {
|
||||
go downloadFontZip(m.font)
|
||||
go downloadFontZip(m.URL)
|
||||
}()
|
||||
|
||||
m.spinner.Spinner = spinner.Globe
|
||||
|
@ -214,20 +233,25 @@ func (m *main) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
return m, tea.Quit
|
||||
|
||||
case "enter":
|
||||
if len(m.font) != 0 || m.list == nil || m.list.SelectedItem() == nil {
|
||||
if len(m.URL) != 0 || m.list == nil || m.list.SelectedItem() == nil {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
var font *Asset
|
||||
var ok bool
|
||||
|
||||
if font, ok = m.list.SelectedItem().(*Asset); !ok {
|
||||
m.err = fmt.Errorf("no font selected")
|
||||
return m, tea.Quit
|
||||
}
|
||||
|
||||
m.state = downloadFont
|
||||
m.font = font.Name
|
||||
m.Asset = *font
|
||||
|
||||
defer func() {
|
||||
go downloadFontZip(font.URL)
|
||||
}()
|
||||
|
||||
m.spinner.Spinner = spinner.Globe
|
||||
return m, m.spinner.Tick
|
||||
|
||||
|
@ -295,11 +319,11 @@ func (m *main) View() string {
|
|||
case selectFont:
|
||||
return fmt.Sprintf("\n%s%s", m.list.View(), terminal.StopProgress())
|
||||
case downloadFont:
|
||||
return textStyle.Render(fmt.Sprintf("%s Downloading %s%s", m.spinner.View(), m.font, terminal.StartProgress()))
|
||||
return textStyle.Render(fmt.Sprintf("%s Downloading %s%s", m.spinner.View(), m.Name, terminal.StartProgress()))
|
||||
case unzipFont:
|
||||
return textStyle.Render(fmt.Sprintf("%s Extracting %s", m.spinner.View(), m.font))
|
||||
return textStyle.Render(fmt.Sprintf("%s Extracting %s", m.spinner.View(), m.Name))
|
||||
case installFont:
|
||||
return textStyle.Render(fmt.Sprintf("%s Installing %s", m.spinner.View(), m.font))
|
||||
return textStyle.Render(fmt.Sprintf("%s Installing %s", m.spinner.View(), m.Name))
|
||||
case quit:
|
||||
return textStyle.Render(fmt.Sprintf("No need to install a new font? That's cool.%s", terminal.StopProgress()))
|
||||
case done:
|
||||
|
@ -309,7 +333,7 @@ func (m *main) View() string {
|
|||
|
||||
var builder strings.Builder
|
||||
|
||||
builder.WriteString(fmt.Sprintf("Successfully installed %s 🚀\n\n%s", m.font, terminal.StopProgress()))
|
||||
builder.WriteString(fmt.Sprintf("Successfully installed %s 🚀\n\n%s", m.Name, terminal.StopProgress()))
|
||||
builder.WriteString("The following font families are now available for configuration:\n\n")
|
||||
|
||||
for i, family := range m.families {
|
||||
|
@ -328,9 +352,12 @@ func (m *main) View() string {
|
|||
|
||||
func Run(font string, ch cache_.Cache, root bool, zipFolder string) {
|
||||
main := &main{
|
||||
font: font,
|
||||
system: root,
|
||||
zipFolder: zipFolder,
|
||||
system: root,
|
||||
Asset: Asset{
|
||||
Name: font,
|
||||
URL: font,
|
||||
Folder: zipFolder,
|
||||
},
|
||||
}
|
||||
|
||||
cache = ch
|
||||
|
|
|
@ -10,25 +10,55 @@ import (
|
|||
"io"
|
||||
httplib "net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
cache_ "github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/http"
|
||||
)
|
||||
|
||||
func Download(fontPath string) ([]byte, error) {
|
||||
u, err := url.Parse(fontPath)
|
||||
func Download(fontURL string) ([]byte, error) {
|
||||
if zipPath, OK := cache.Get(fontURL); OK {
|
||||
if b, err := os.ReadFile(zipPath); err == nil {
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
// validate if we have a local file
|
||||
u, err := url.Parse(fontURL)
|
||||
if err != nil || u.Scheme != "https" {
|
||||
return nil, errors.New("font path must be a valid URL")
|
||||
}
|
||||
|
||||
var b []byte
|
||||
if b, err = getRemoteFile(fontPath); err != nil {
|
||||
if b, err = getRemoteFile(fontURL); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !isZipFile(b) {
|
||||
return nil, fmt.Errorf("%s is not a valid zip file", fontPath)
|
||||
return nil, fmt.Errorf("%s is not a valid zip file", fontURL)
|
||||
}
|
||||
|
||||
fileName := path.Base(fontURL)
|
||||
|
||||
zipPath := filepath.Join(os.TempDir(), fileName)
|
||||
tempFile, err := os.Create(zipPath)
|
||||
defer func() {
|
||||
_ = tempFile.Close()
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
_, err = tempFile.Write(b)
|
||||
if err != nil {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
cache.Set(fontURL, zipPath, cache_.ONEDAY)
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
|
@ -42,10 +72,12 @@ func getRemoteFile(location string) (data []byte, err error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := http.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != httplib.StatusOK {
|
||||
|
|
|
@ -23,9 +23,10 @@ type release struct {
|
|||
}
|
||||
|
||||
type Asset struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"browser_download_url"`
|
||||
State string `json:"state"`
|
||||
Name string `json:"name"`
|
||||
URL string `json:"browser_download_url"`
|
||||
State string `json:"state"`
|
||||
Folder string `json:"folder"`
|
||||
}
|
||||
|
||||
func (a Asset) FilterValue() string { return a.Name }
|
||||
|
@ -42,7 +43,7 @@ func Fonts() ([]*Asset, error) {
|
|||
|
||||
cascadiaCode, err := CascadiaCode()
|
||||
if err == nil {
|
||||
assets = append(assets, cascadiaCode)
|
||||
assets = append(assets, cascadiaCode...)
|
||||
}
|
||||
|
||||
sort.Slice(assets, func(i, j int) bool { return assets[i].Name < assets[j].Name })
|
||||
|
@ -84,16 +85,39 @@ func setCachedFontData(assets []*Asset) {
|
|||
cache.Set(cache_.FONTLISTCACHE, string(data), cache_.ONEDAY)
|
||||
}
|
||||
|
||||
func CascadiaCode() (*Asset, error) {
|
||||
func CascadiaCode() ([]*Asset, error) {
|
||||
assets, err := fetchFontAssets("microsoft/cascadia-code")
|
||||
if err != nil || len(assets) != 1 {
|
||||
return nil, errors.New("no assets found")
|
||||
}
|
||||
|
||||
// patch the name
|
||||
assets[0].Name = CascadiaCodeMS
|
||||
|
||||
return assets[0], nil
|
||||
return []*Asset{
|
||||
{
|
||||
Name: fmt.Sprintf("%s - TTF", CascadiaCodeMS),
|
||||
URL: assets[0].URL,
|
||||
Folder: "ttf/",
|
||||
},
|
||||
{
|
||||
Name: fmt.Sprintf("%s - TTF Static", CascadiaCodeMS),
|
||||
URL: assets[0].URL,
|
||||
Folder: "ttf/static/",
|
||||
},
|
||||
{
|
||||
Name: fmt.Sprintf("%s - OTF Static", CascadiaCodeMS),
|
||||
URL: assets[0].URL,
|
||||
Folder: "otf/static/",
|
||||
},
|
||||
{
|
||||
Name: fmt.Sprintf("%s - WOFF2", CascadiaCodeMS),
|
||||
URL: assets[0].URL,
|
||||
Folder: "woff2/static/",
|
||||
},
|
||||
{
|
||||
Name: fmt.Sprintf("%s - WOFF2 Static", CascadiaCodeMS),
|
||||
URL: assets[0].URL,
|
||||
Folder: "woff2/static/",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func fetchFontAssets(repo string) ([]*Asset, error) {
|
||||
|
|
|
@ -45,7 +45,7 @@ func InstallZIP(data []byte, m *main) ([]string, error) {
|
|||
}
|
||||
|
||||
fontFileName := path.Base(file.Name)
|
||||
fontRelativeFileName := strings.TrimPrefix(file.Name, m.zipFolder)
|
||||
fontRelativeFileName := strings.TrimPrefix(file.Name, m.Folder)
|
||||
|
||||
// do not install fonts that are not in the specified installation folder
|
||||
if fontFileName != fontRelativeFileName {
|
||||
|
|
|
@ -36,7 +36,7 @@ import (
|
|||
"unicode/utf8"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
fontCLI "github.com/jandedobbeleer/oh-my-posh/src/font"
|
||||
font_ "github.com/jandedobbeleer/oh-my-posh/src/font"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/regex"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
|
||||
|
@ -229,7 +229,7 @@ func (ir *Renderer) loadFonts() error {
|
|||
url := "https://github.com/ryanoasis/nerd-fonts/releases/download/v3.2.1/Hack.zip"
|
||||
var err error
|
||||
|
||||
data, err = fontCLI.Download(url)
|
||||
data, err = font_.Download(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -47,12 +47,6 @@ This will present a list of Nerd Font libraries, from which you can select `Mes
|
|||
oh-my-posh font install meslo
|
||||
```
|
||||
|
||||
If you have a font that has specific flavors of a font inside sub folders, you can specify the sub folder name:
|
||||
|
||||
```bash
|
||||
oh-my-posh font install --zip-folder ttf/static "CascadiaCode (MS)"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="homebrew">
|
||||
|
||||
|
|
Loading…
Reference in a new issue