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
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var args []string
|
editor = strings.TrimSpace(editor)
|
||||||
if strings.Contains(editor, " ") {
|
args := strings.Split(editor, " ")
|
||||||
strs := strings.Split(editor, " ")
|
|
||||||
editor = strs[0]
|
editor = args[0]
|
||||||
args = strs[1:]
|
args = append(args[1:], file)
|
||||||
}
|
|
||||||
|
|
||||||
args = append(args, file)
|
|
||||||
cmd := exec.Command(editor, args...)
|
cmd := exec.Command(editor, args...)
|
||||||
|
|
||||||
err := cmd.Run()
|
cmd.Stdin = os.Stdin
|
||||||
if err != nil {
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd.ProcessState.ExitCode()
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,14 +72,13 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type main struct {
|
type main struct {
|
||||||
err error
|
err error
|
||||||
list *list.Model
|
list *list.Model
|
||||||
font string
|
Asset
|
||||||
zipFolder string
|
families []string
|
||||||
families []string
|
spinner spinner.Model
|
||||||
spinner spinner.Model
|
state state
|
||||||
state state
|
system bool
|
||||||
system bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *main) buildFontList(nerdFonts []*Asset) {
|
func (m *main) buildFontList(nerdFonts []*Asset) {
|
||||||
|
@ -122,7 +121,7 @@ func downloadFontZip(location string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func installLocalFontZIP(m *main) {
|
func installLocalFontZIP(m *main) {
|
||||||
data, err := os.ReadFile(m.font)
|
data, err := os.ReadFile(m.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
program.Send(errMsg(err))
|
program.Send(errMsg(err))
|
||||||
return
|
return
|
||||||
|
@ -143,28 +142,48 @@ func installFontZIP(zipFile []byte, m *main) {
|
||||||
|
|
||||||
func (m *main) Init() tea.Cmd {
|
func (m *main) Init() tea.Cmd {
|
||||||
isLocalZipFile := func() bool {
|
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
|
m.state = downloadFont
|
||||||
|
|
||||||
if !strings.HasPrefix(m.font, "https") {
|
if err := resolveFontZipURL(); err != nil {
|
||||||
if m.font == CascadiaCodeMS {
|
m.err = err
|
||||||
cascadia, err := CascadiaCode()
|
return tea.Quit
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
go downloadFontZip(m.font)
|
go downloadFontZip(m.URL)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
m.spinner.Spinner = spinner.Globe
|
m.spinner.Spinner = spinner.Globe
|
||||||
|
@ -214,20 +233,25 @@ func (m *main) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
return m, tea.Quit
|
return m, tea.Quit
|
||||||
|
|
||||||
case "enter":
|
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
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var font *Asset
|
var font *Asset
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
if font, ok = m.list.SelectedItem().(*Asset); !ok {
|
if font, ok = m.list.SelectedItem().(*Asset); !ok {
|
||||||
m.err = fmt.Errorf("no font selected")
|
m.err = fmt.Errorf("no font selected")
|
||||||
return m, tea.Quit
|
return m, tea.Quit
|
||||||
}
|
}
|
||||||
|
|
||||||
m.state = downloadFont
|
m.state = downloadFont
|
||||||
m.font = font.Name
|
m.Asset = *font
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
go downloadFontZip(font.URL)
|
go downloadFontZip(font.URL)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
m.spinner.Spinner = spinner.Globe
|
m.spinner.Spinner = spinner.Globe
|
||||||
return m, m.spinner.Tick
|
return m, m.spinner.Tick
|
||||||
|
|
||||||
|
@ -295,11 +319,11 @@ func (m *main) View() string {
|
||||||
case selectFont:
|
case selectFont:
|
||||||
return fmt.Sprintf("\n%s%s", m.list.View(), terminal.StopProgress())
|
return fmt.Sprintf("\n%s%s", m.list.View(), terminal.StopProgress())
|
||||||
case downloadFont:
|
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:
|
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:
|
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:
|
case quit:
|
||||||
return textStyle.Render(fmt.Sprintf("No need to install a new font? That's cool.%s", terminal.StopProgress()))
|
return textStyle.Render(fmt.Sprintf("No need to install a new font? That's cool.%s", terminal.StopProgress()))
|
||||||
case done:
|
case done:
|
||||||
|
@ -309,7 +333,7 @@ func (m *main) View() string {
|
||||||
|
|
||||||
var builder strings.Builder
|
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")
|
builder.WriteString("The following font families are now available for configuration:\n\n")
|
||||||
|
|
||||||
for i, family := range m.families {
|
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) {
|
func Run(font string, ch cache_.Cache, root bool, zipFolder string) {
|
||||||
main := &main{
|
main := &main{
|
||||||
font: font,
|
system: root,
|
||||||
system: root,
|
Asset: Asset{
|
||||||
zipFolder: zipFolder,
|
Name: font,
|
||||||
|
URL: font,
|
||||||
|
Folder: zipFolder,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cache = ch
|
cache = ch
|
||||||
|
|
|
@ -10,25 +10,55 @@ import (
|
||||||
"io"
|
"io"
|
||||||
httplib "net/http"
|
httplib "net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
cache_ "github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/http"
|
"github.com/jandedobbeleer/oh-my-posh/src/runtime/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Download(fontPath string) ([]byte, error) {
|
func Download(fontURL string) ([]byte, error) {
|
||||||
u, err := url.Parse(fontPath)
|
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" {
|
if err != nil || u.Scheme != "https" {
|
||||||
return nil, errors.New("font path must be a valid URL")
|
return nil, errors.New("font path must be a valid URL")
|
||||||
}
|
}
|
||||||
|
|
||||||
var b []byte
|
var b []byte
|
||||||
if b, err = getRemoteFile(fontPath); err != nil {
|
if b, err = getRemoteFile(fontURL); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isZipFile(b) {
|
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
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,10 +72,12 @@ func getRemoteFile(location string) (data []byte, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := http.HTTPClient.Do(req)
|
resp, err := http.HTTPClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != httplib.StatusOK {
|
if resp.StatusCode != httplib.StatusOK {
|
||||||
|
|
|
@ -23,9 +23,10 @@ type release struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Asset struct {
|
type Asset struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
URL string `json:"browser_download_url"`
|
URL string `json:"browser_download_url"`
|
||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
|
Folder string `json:"folder"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Asset) FilterValue() string { return a.Name }
|
func (a Asset) FilterValue() string { return a.Name }
|
||||||
|
@ -42,7 +43,7 @@ func Fonts() ([]*Asset, error) {
|
||||||
|
|
||||||
cascadiaCode, err := CascadiaCode()
|
cascadiaCode, err := CascadiaCode()
|
||||||
if err == nil {
|
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 })
|
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)
|
cache.Set(cache_.FONTLISTCACHE, string(data), cache_.ONEDAY)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CascadiaCode() (*Asset, error) {
|
func CascadiaCode() ([]*Asset, error) {
|
||||||
assets, err := fetchFontAssets("microsoft/cascadia-code")
|
assets, err := fetchFontAssets("microsoft/cascadia-code")
|
||||||
if err != nil || len(assets) != 1 {
|
if err != nil || len(assets) != 1 {
|
||||||
return nil, errors.New("no assets found")
|
return nil, errors.New("no assets found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// patch the name
|
return []*Asset{
|
||||||
assets[0].Name = CascadiaCodeMS
|
{
|
||||||
|
Name: fmt.Sprintf("%s - TTF", CascadiaCodeMS),
|
||||||
return assets[0], nil
|
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) {
|
func fetchFontAssets(repo string) ([]*Asset, error) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ func InstallZIP(data []byte, m *main) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fontFileName := path.Base(file.Name)
|
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
|
// do not install fonts that are not in the specified installation folder
|
||||||
if fontFileName != fontRelativeFileName {
|
if fontFileName != fontRelativeFileName {
|
||||||
|
|
|
@ -36,7 +36,7 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
"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/regex"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
|
"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"
|
url := "https://github.com/ryanoasis/nerd-fonts/releases/download/v3.2.1/Hack.zip"
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
data, err = fontCLI.Download(url)
|
data, err = font_.Download(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
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>
|
||||||
<TabItem value="homebrew">
|
<TabItem value="homebrew">
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue