mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2026-08-24 02:34:19 -05:00
refactor(cli)!: give fonts a list and an install command
Choosing a font was a five-stage terminal UI: fetch the list, scroll it, download, unzip, install. It pulled bubbletea, lipgloss, bubbles and a fuzzy matcher for what amounted to a non-filtering list of names with one highlighted - and Go runs a linked package's init before main whether or not the subcommand was invoked, so everyone typing at a prompt paid for it on every render. A CLI already has a way to answer "which fonts are there": print them. oh-my-posh font list oh-my-posh font install Meslo The list can be grepped, piped and scripted, none of which a picker allows, and install is what it always was underneath - resolve, fetch, unzip - now reporting on a status line and a progress bar. Removes 20 modules including go-runewidth, whose package init built a 2.2MB lookup table nothing in the prompt path ever read. The atotto/clipboard fork this repo carried goes with them: bubbletea was the only thing that needed it. Binary 17,330,176 to 15,981,056 bytes (-7.8%). Init, median of 11 runs, 39.3ms to 6.8ms - on every invocation, prompt renders included. BREAKING CHANGE: `oh-my-posh font install` now requires a font name; run `oh-my-posh font list` to see them. The interactive picker is gone, and with it the --headless flag, which existed to skip it. Entire-Checkpoint: ef231d69c9bf
This commit is contained in:
committed by
Jan De Dobbeleer
parent
cc8c2add4a
commit
3b63012568
+76
-59
@@ -17,82 +17,99 @@ import (
|
||||
|
||||
var (
|
||||
zipFolder string
|
||||
headless bool
|
||||
|
||||
fontCmd = &cobra.Command{
|
||||
Use: "font [install|configure]",
|
||||
Use: "font",
|
||||
Short: "Manage fonts",
|
||||
Long: `Manage fonts.
|
||||
|
||||
This command is used to install fonts and configure the font in your terminal.
|
||||
List the available Nerd Fonts and install one:
|
||||
|
||||
- install: oh-my-posh font install 3270`,
|
||||
ValidArgs: []string{
|
||||
"install",
|
||||
"configure",
|
||||
oh-my-posh font list
|
||||
oh-my-posh font install Meslo`,
|
||||
}
|
||||
|
||||
fontListCmd = &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List the available Nerd Fonts",
|
||||
Long: `List the available Nerd Fonts.
|
||||
|
||||
Prints one font name per line, so it can be searched or piped:
|
||||
|
||||
oh-my-posh font list | grep -i mono`,
|
||||
Args: cobra.NoArgs,
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
fonts, err := font.List()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
exitcode = 70
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for _, f := range fonts {
|
||||
fmt.Println(f.Name)
|
||||
}
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
_ = cmd.Help()
|
||||
}
|
||||
|
||||
fontInstallCmd = &cobra.Command{
|
||||
Use: "install <font>",
|
||||
Short: "Install a Nerd Font",
|
||||
Long: `Install a Nerd Font.
|
||||
|
||||
Takes a font name from ` + "`oh-my-posh font list`" + `, a URL, or the path to a local zip file:
|
||||
|
||||
oh-my-posh font install Meslo
|
||||
oh-my-posh font install https://example.com/font.zip
|
||||
oh-my-posh font install ./CascadiaCode.zip`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
env := &runtime.Terminal{}
|
||||
env.Init(&runtime.Flags{})
|
||||
|
||||
sh := env.Shell()
|
||||
|
||||
cache.Init(sh, cache.Persist)
|
||||
|
||||
defer cache.Close()
|
||||
|
||||
terminal.Init(sh)
|
||||
|
||||
cfg := config.Get(configFlag, false)
|
||||
cfg.TerminalFeatures.Apply()
|
||||
|
||||
if zipFolder != "" && !strings.HasPrefix(zipFolder, "/") {
|
||||
zipFolder += "/"
|
||||
}
|
||||
|
||||
fontName, err := font.Install(args[0], zipFolder)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
exitcode = 70
|
||||
|
||||
return
|
||||
}
|
||||
switch args[0] {
|
||||
case "install":
|
||||
var fontName string
|
||||
if len(args) > 1 {
|
||||
fontName = args[1]
|
||||
}
|
||||
|
||||
env := &runtime.Terminal{}
|
||||
env.Init(&runtime.Flags{})
|
||||
|
||||
sh := env.Shell()
|
||||
|
||||
cache.Init(sh, cache.Persist)
|
||||
|
||||
defer func() {
|
||||
cache.Close()
|
||||
}()
|
||||
|
||||
terminal.Init(sh)
|
||||
|
||||
cfg := config.Get(configFlag, false)
|
||||
cfg.TerminalFeatures.Apply()
|
||||
|
||||
if !strings.HasPrefix(zipFolder, "/") {
|
||||
zipFolder += "/"
|
||||
}
|
||||
|
||||
fontName, err := font.Run(fontName, zipFolder, headless)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
exitcode = 70
|
||||
return
|
||||
}
|
||||
|
||||
if env.Root() {
|
||||
// do not update the DSC cache if we are running as root
|
||||
return
|
||||
}
|
||||
|
||||
fontDSC := font.DSC()
|
||||
fontDSC.Load()
|
||||
fontDSC.Add(fontName)
|
||||
fontDSC.Save()
|
||||
|
||||
if env.Root() {
|
||||
// do not update the DSC cache if we are running as root
|
||||
return
|
||||
case "configure":
|
||||
fmt.Println("not implemented")
|
||||
default:
|
||||
_ = cmd.Help()
|
||||
}
|
||||
|
||||
fontDSC := font.DSC()
|
||||
fontDSC.Load()
|
||||
fontDSC.Add(fontName)
|
||||
fontDSC.Save()
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
fontCmd.Flags().StringVar(&zipFolder, "zip-folder", "", "the folder inside the zip file to install fonts from")
|
||||
fontCmd.Flags().BoolVar(&headless, "headless", false, "install font without TUI")
|
||||
fontInstallCmd.Flags().StringVar(&zipFolder, "zip-folder", "", "the folder inside the zip file to install fonts from")
|
||||
|
||||
fontCmd.AddCommand(fontListCmd)
|
||||
fontCmd.AddCommand(fontInstallCmd)
|
||||
fontCmd.AddCommand(dsc.Command(font.DSC()))
|
||||
|
||||
RootCmd.AddCommand(fontCmd)
|
||||
}
|
||||
|
||||
@@ -12,11 +12,13 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cache"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cli/progress"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cli/ui"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime/http"
|
||||
)
|
||||
|
||||
func Download(fontURL string) ([]byte, error) {
|
||||
// download fetches a font zip, reporting how much has arrived so a caller can draw a bar. report
|
||||
// may be nil, which is what the DSC path and the tests pass.
|
||||
func download(fontURL string, report func(fraction float64)) ([]byte, error) {
|
||||
if zipPath, OK := cache.Get[string](cache.Device, fontURL); OK {
|
||||
if b, err := os.ReadFile(zipPath); err == nil {
|
||||
return b, nil
|
||||
@@ -30,7 +32,7 @@ func Download(fontURL string) ([]byte, error) {
|
||||
}
|
||||
|
||||
var b []byte
|
||||
if b, err = getRemoteFile(fontURL); err != nil {
|
||||
if b, err = getRemoteFile(fontURL, report); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -65,7 +67,7 @@ func isZipFile(data []byte) bool {
|
||||
return contentType == "application/zip"
|
||||
}
|
||||
|
||||
func getRemoteFile(location string) (data []byte, err error) {
|
||||
func getRemoteFile(location string, report func(fraction float64)) (data []byte, err error) {
|
||||
req, err := httplib.NewRequestWithContext(context.Background(), "GET", location, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -82,7 +84,7 @@ func getRemoteFile(location string) (data []byte, err error) {
|
||||
return data, fmt.Errorf("failed to download zip file: %s\n→ %s", resp.Status, location)
|
||||
}
|
||||
|
||||
reader := progress.NewReader(resp.Body, resp.ContentLength, program)
|
||||
reader := ui.NewReader(resp.Body, resp.ContentLength, report)
|
||||
|
||||
data, err = io.ReadAll(reader)
|
||||
if err != nil {
|
||||
@@ -91,3 +93,9 @@ func getRemoteFile(location string) (data []byte, err error) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Download keeps the old name for callers that need no progress reporting (see font.Apply, which
|
||||
// runs under DSC with nothing drawing).
|
||||
func Download(fontURL string) ([]byte, error) {
|
||||
return download(fontURL, nil)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package font
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cli/ui"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/text"
|
||||
)
|
||||
|
||||
// List returns the installable Nerd Fonts, newest release first, for `oh-my-posh font list`.
|
||||
func List() ([]*Asset, error) {
|
||||
return fonts()
|
||||
}
|
||||
|
||||
// Install downloads and installs one font by name, URL, or local zip path, reporting each step on
|
||||
// a status line.
|
||||
//
|
||||
// This replaced a five-stage terminal UI - fetch the list, pick from it, download, unzip, install
|
||||
// - that existed only so a name could be chosen interactively. `font list` answers that question
|
||||
// better: it can be read, grepped, scripted, and piped, none of which a picker allows. What is
|
||||
// left is a linear sequence, which is what it always was underneath.
|
||||
func Install(name, zipFolder string) (string, error) {
|
||||
status := ui.NewStatus(os.Stdout)
|
||||
|
||||
// A local zip is already on disk: nothing to resolve and nothing to download.
|
||||
if IsLocalZipFile(name) {
|
||||
data, err := os.ReadFile(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
status.Start(fmt.Sprintf("Installing %s", name))
|
||||
|
||||
families, err := InstallZIP(data, zipFolder)
|
||||
if err != nil {
|
||||
status.Stop("")
|
||||
return "", err
|
||||
}
|
||||
|
||||
status.Stop(installed(name, families))
|
||||
|
||||
return name, nil
|
||||
}
|
||||
|
||||
status.Start("Resolving font")
|
||||
|
||||
asset, err := ResolveFontAsset(name)
|
||||
if err != nil {
|
||||
status.Stop("")
|
||||
return "", err
|
||||
}
|
||||
|
||||
if asset.Folder != "" && zipFolder == "" {
|
||||
zipFolder = asset.Folder
|
||||
}
|
||||
|
||||
status.Stop("")
|
||||
|
||||
bar := ui.NewProgress(os.Stdout, fmt.Sprintf("Downloading %s", asset.Name))
|
||||
|
||||
zipFile, err := download(asset.URL, bar.Set)
|
||||
if err != nil {
|
||||
bar.Done()
|
||||
return "", err
|
||||
}
|
||||
|
||||
bar.Done()
|
||||
|
||||
status.Start(fmt.Sprintf("Installing %s", asset.Name))
|
||||
|
||||
families, err := InstallZIP(zipFile, zipFolder)
|
||||
if err != nil {
|
||||
status.Stop("")
|
||||
return "", err
|
||||
}
|
||||
|
||||
status.Stop(installed(asset.Name, families))
|
||||
|
||||
return asset.Name, nil
|
||||
}
|
||||
|
||||
// installed words the closing line: which families a shell can now be pointed at, since the
|
||||
// family name is rarely the name of the font that was asked for.
|
||||
func installed(name string, families []string) string {
|
||||
if len(families) == 0 {
|
||||
return fmt.Sprintf("No matching font families were installed. Try --zip-folder when installing %s or a custom font zip.", name)
|
||||
}
|
||||
|
||||
sb := text.NewBuilder()
|
||||
|
||||
sb.WriteString(fmt.Sprintf("Installed %s 🚀\n\nThe following font families are now available for configuration:\n", name))
|
||||
|
||||
for _, family := range families {
|
||||
sb.WriteString(fmt.Sprintf("\n • %s", family))
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
@@ -1,366 +0,0 @@
|
||||
package font
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/bubbles/list"
|
||||
progress_ "github.com/charmbracelet/bubbles/progress"
|
||||
"github.com/charmbracelet/bubbles/spinner"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/cli/progress"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/text"
|
||||
)
|
||||
|
||||
var (
|
||||
program *tea.Program
|
||||
)
|
||||
|
||||
const listHeight = 14
|
||||
|
||||
var (
|
||||
itemStyle = lipgloss.NewStyle().PaddingLeft(3)
|
||||
selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("170"))
|
||||
paginationStyle = list.DefaultStyles().PaginationStyle.PaddingLeft(3)
|
||||
helpStyle = lipgloss.NewStyle().PaddingLeft(3).PaddingBottom(1)
|
||||
textStyle = lipgloss.NewStyle().Margin(1, 0, 2, 2)
|
||||
)
|
||||
|
||||
type loadMsg []*Asset
|
||||
|
||||
type zipMsg []byte
|
||||
|
||||
type successMsg []string
|
||||
|
||||
type errMsg error
|
||||
|
||||
type state int
|
||||
|
||||
type itemDelegate struct{}
|
||||
|
||||
func (d itemDelegate) Height() int { return 1 }
|
||||
func (d itemDelegate) Spacing() int { return 0 }
|
||||
func (d itemDelegate) Update(_ tea.Msg, _ *list.Model) tea.Cmd { return nil }
|
||||
func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) { //nolint: gocritic
|
||||
i, ok := listItem.(*Asset)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
fn := itemStyle.Render
|
||||
if index == m.Index() {
|
||||
fn = func(s ...string) string {
|
||||
return selectedItemStyle.Render("•" + strings.Join(s, " "))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprint(w, fn(i.Name))
|
||||
}
|
||||
|
||||
const (
|
||||
getFonts state = iota
|
||||
selectFont
|
||||
downloadFont
|
||||
unzipFont
|
||||
installFont
|
||||
quit
|
||||
done
|
||||
)
|
||||
|
||||
type main struct {
|
||||
err error
|
||||
list *list.Model
|
||||
spinner *spinner.Model
|
||||
progress *progress.Model
|
||||
Asset
|
||||
families []string
|
||||
state state
|
||||
}
|
||||
|
||||
func (m *main) buildFontList(nerdFonts []*Asset) {
|
||||
var items []list.Item
|
||||
for _, font := range nerdFonts {
|
||||
items = append(items, font)
|
||||
}
|
||||
|
||||
const defaultWidth = 20
|
||||
|
||||
l := list.New(items, itemDelegate{}, defaultWidth, listHeight)
|
||||
l.Title = "Select font"
|
||||
l.SetShowStatusBar(false)
|
||||
l.SetFilteringEnabled(false)
|
||||
l.Styles.PaginationStyle = paginationStyle
|
||||
l.Styles.HelpStyle = helpStyle
|
||||
|
||||
m.list = &l
|
||||
}
|
||||
|
||||
func getFontsList() {
|
||||
fonts, err := fonts()
|
||||
if err != nil {
|
||||
program.Send(errMsg(err))
|
||||
return
|
||||
}
|
||||
|
||||
program.Send(loadMsg(fonts))
|
||||
}
|
||||
|
||||
func downloadFontZip(location string) {
|
||||
zipFile, err := Download(location)
|
||||
if err != nil {
|
||||
program.Send(errMsg(err))
|
||||
return
|
||||
}
|
||||
|
||||
program.Send(zipMsg(zipFile))
|
||||
}
|
||||
|
||||
func installLocalFontZIP(m *main) {
|
||||
data, err := os.ReadFile(m.URL)
|
||||
if err != nil {
|
||||
program.Send(errMsg(err))
|
||||
return
|
||||
}
|
||||
|
||||
installFontZIP(data, m)
|
||||
}
|
||||
|
||||
func installFontZIP(zipFile []byte, m *main) {
|
||||
families, err := InstallZIP(zipFile, m.Folder)
|
||||
if err != nil {
|
||||
program.Send(errMsg(err))
|
||||
return
|
||||
}
|
||||
|
||||
program.Send(successMsg(families))
|
||||
}
|
||||
|
||||
func (m *main) Init() tea.Cmd {
|
||||
m.progress = progress.NewModel()
|
||||
|
||||
s := spinner.New()
|
||||
m.spinner = &s
|
||||
|
||||
if len(m.URL) != 0 && !IsLocalZipFile(m.URL) {
|
||||
m.state = downloadFont
|
||||
|
||||
asset, err := ResolveFontAsset(m.URL)
|
||||
if err != nil {
|
||||
m.err = err
|
||||
return tea.Quit
|
||||
}
|
||||
|
||||
m.Asset = *asset
|
||||
|
||||
defer func() {
|
||||
go downloadFontZip(asset.URL)
|
||||
}()
|
||||
|
||||
m.spinner.Spinner = spinner.Globe
|
||||
return m.spinner.Tick
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if IsLocalZipFile(m.URL) {
|
||||
go installLocalFontZIP(m)
|
||||
return
|
||||
}
|
||||
|
||||
go getFontsList()
|
||||
}()
|
||||
|
||||
m.spinner.Spinner = spinner.Dot
|
||||
m.spinner.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("170"))
|
||||
m.state = getFonts
|
||||
|
||||
if IsLocalZipFile(m.URL) {
|
||||
m.state = unzipFont
|
||||
}
|
||||
|
||||
return m.spinner.Tick
|
||||
}
|
||||
|
||||
func (m *main) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case loadMsg:
|
||||
m.state = selectFont
|
||||
m.buildFontList(msg)
|
||||
return m, nil
|
||||
|
||||
case tea.WindowSizeMsg:
|
||||
if m.list == nil {
|
||||
return m, nil
|
||||
}
|
||||
m.list.SetWidth(msg.Width)
|
||||
return m, nil
|
||||
|
||||
case tea.KeyMsg:
|
||||
switch keypress := msg.String(); keypress {
|
||||
case "ctrl+c", "q", "esc":
|
||||
m.state = quit
|
||||
return m, tea.Quit
|
||||
|
||||
case "enter":
|
||||
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.Asset = *font
|
||||
|
||||
defer func() {
|
||||
go downloadFontZip(font.URL)
|
||||
}()
|
||||
|
||||
m.spinner.Spinner = spinner.Globe
|
||||
return m, m.spinner.Tick
|
||||
|
||||
case "up", "k":
|
||||
if m.list != nil {
|
||||
if m.list.Index() == 0 {
|
||||
m.list.Select(len(m.list.Items()) - 1)
|
||||
} else {
|
||||
m.list.Select(m.list.Index() - 1)
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
|
||||
case "down", "j":
|
||||
if m.list != nil {
|
||||
if m.list.Index() == len(m.list.Items())-1 {
|
||||
m.list.Select(0)
|
||||
} else {
|
||||
m.list.Select(m.list.Index() + 1)
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
case progress.Message:
|
||||
return m, m.progress.SetPercent(float64(msg))
|
||||
|
||||
case progress_.FrameMsg:
|
||||
return m, m.progress.Update(msg)
|
||||
|
||||
case zipMsg:
|
||||
m.state = installFont
|
||||
defer func() {
|
||||
go installFontZIP(msg, m)
|
||||
}()
|
||||
m.spinner.Spinner = spinner.Dot
|
||||
return m, m.spinner.Tick
|
||||
|
||||
case successMsg:
|
||||
m.state = done
|
||||
m.families = msg
|
||||
return m, tea.Quit
|
||||
|
||||
case errMsg:
|
||||
m.err = msg
|
||||
return m, tea.Quit
|
||||
|
||||
default:
|
||||
s, cmd := m.spinner.Update(msg)
|
||||
m.spinner = &s
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
if m.list == nil {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
lst, cmd := m.list.Update(msg)
|
||||
m.list = &lst
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
func (m *main) View() string {
|
||||
if m.err != nil {
|
||||
return textStyle.Render(m.err.Error())
|
||||
}
|
||||
|
||||
switch m.state {
|
||||
case getFonts:
|
||||
return textStyle.Render(fmt.Sprintf("%s Downloading font list%s", m.spinner.View(), terminal.StartProgress()))
|
||||
case selectFont:
|
||||
return fmt.Sprintf("\n%s%s", m.list.View(), terminal.StopProgress())
|
||||
case downloadFont:
|
||||
return textStyle.Render(fmt.Sprintf("Downloading %s...\n%s", m.Name, m.progress.View()))
|
||||
case unzipFont:
|
||||
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.Name))
|
||||
case quit:
|
||||
return textStyle.Render(fmt.Sprintf("No need to install a new font? That's cool.%s", terminal.StopProgress()))
|
||||
case done:
|
||||
if len(m.families) == 0 {
|
||||
return textStyle.Render(fmt.Sprintf("No matching font families were installed. Try setting --zip-folder to the correct folder when using CascadiaCode (MS) or a custom font zip file. %s", terminal.StopProgress())) //nolint: lll
|
||||
}
|
||||
|
||||
sb := text.NewBuilder()
|
||||
|
||||
sb.WriteString(fmt.Sprintf("Successfully installed %s 🚀\n\n%s", m.Name, terminal.StopProgress()))
|
||||
sb.WriteString("The following font families are now available for configuration:\n\n")
|
||||
|
||||
for i, family := range m.families {
|
||||
sb.WriteString(fmt.Sprintf(" • %s", family))
|
||||
|
||||
if i < len(m.families)-1 {
|
||||
sb.WriteString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
return textStyle.Render(sb.String())
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func Run(font, zipFolder string, headless bool) (string, error) {
|
||||
if headless {
|
||||
return installHeadless(font, zipFolder)
|
||||
}
|
||||
|
||||
return tui(font, zipFolder)
|
||||
}
|
||||
|
||||
func tui(font, zipFolder string) (string, error) {
|
||||
main := &main{
|
||||
Asset: Asset{
|
||||
Name: font,
|
||||
URL: font,
|
||||
Folder: zipFolder,
|
||||
},
|
||||
}
|
||||
|
||||
program = tea.NewProgram(main)
|
||||
_, err := program.Run()
|
||||
return main.Name, err
|
||||
}
|
||||
|
||||
func installHeadless(font, zipFolder string) (string, error) {
|
||||
// Handle local zip file
|
||||
if IsLocalZipFile(font) {
|
||||
data, err := os.ReadFile(font)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, err = InstallZIP(data, zipFolder)
|
||||
return font, err
|
||||
}
|
||||
|
||||
return downloadAndInstall(font, zipFolder)
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package progress
|
||||
|
||||
import (
|
||||
"github.com/charmbracelet/bubbles/progress"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
|
||||
)
|
||||
|
||||
type Message float64
|
||||
|
||||
func NewModel() *Model {
|
||||
p := progress.New(progress.WithScaledGradient("#800080", "#ffc0cb"))
|
||||
return &Model{Model: p}
|
||||
}
|
||||
|
||||
type Model struct {
|
||||
progress.Model
|
||||
}
|
||||
|
||||
func (m *Model) Update(msg tea.Msg) tea.Cmd {
|
||||
model, cmd := m.Model.Update(msg)
|
||||
m.Model = model.(progress.Model)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (m *Model) View() string {
|
||||
return m.Model.View() + terminal.SetProgress(int(m.Percent()*100))
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package progress
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
func NewReader(reader io.Reader, total int64, program *tea.Program) *Reader {
|
||||
return &Reader{
|
||||
Reader: reader,
|
||||
program: program,
|
||||
total: total,
|
||||
}
|
||||
}
|
||||
|
||||
type Reader struct {
|
||||
io.Reader
|
||||
|
||||
program *tea.Program
|
||||
total int64
|
||||
current int64
|
||||
}
|
||||
|
||||
func (r *Reader) Read(p []byte) (int, error) {
|
||||
n, err := r.Reader.Read(p)
|
||||
r.current += int64(n)
|
||||
percent := float64(r.current) / float64(r.total)
|
||||
|
||||
if r.program != nil {
|
||||
r.program.Send(Message(percent))
|
||||
}
|
||||
|
||||
return n, err
|
||||
}
|
||||
-22
@@ -24,9 +24,6 @@ require (
|
||||
|
||||
require (
|
||||
github.com/ConradIrwin/font v0.2.1
|
||||
github.com/charmbracelet/bubbles v1.0.0
|
||||
github.com/charmbracelet/bubbletea v1.3.10
|
||||
github.com/charmbracelet/lipgloss v1.1.0
|
||||
github.com/gookit/goutil v0.8.0
|
||||
github.com/hashicorp/hcl/v2 v2.24.0
|
||||
github.com/invopop/jsonschema v0.14.0
|
||||
@@ -59,32 +56,15 @@ require (
|
||||
dmitri.shuralyov.com/font/woff2 v0.0.0-20180220214647-957792cbbdab // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.2 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.4.1 // indirect
|
||||
github.com/charmbracelet/harmonica v0.2.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.11.6 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.15 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.2 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.10.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.6.0 // indirect
|
||||
github.com/dsnet/compress v0.0.1 // indirect
|
||||
github.com/ebitengine/purego v0.10.0 // indirect
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.27 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/termenv v0.16.0 // indirect
|
||||
github.com/pb33f/ordered-map/v2 v2.3.1 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sahilm/fuzzy v0.1.1 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zclconf/go-cty v1.17.0 // indirect
|
||||
@@ -94,5 +74,3 @@ require (
|
||||
golang.org/x/tools v0.47.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/atotto/clipboard v0.1.4 => github.com/jandedobbeleer/clipboard v0.1.4-1
|
||||
|
||||
-47
@@ -22,36 +22,10 @@ github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs
|
||||
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/aymanbagabas/go-udiff v0.3.1 h1:LV+qyBQ2pqe0u42ZsUEtPiCaUoqgA9gYRDs3vj1nolY=
|
||||
github.com/aymanbagabas/go-udiff v0.3.1/go.mod h1:G0fsKmG+P6ylD0r6N/KgQD/nWzgfnl8ZBcNLgcbrw8E=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk=
|
||||
github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc=
|
||||
github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E=
|
||||
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
|
||||
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
|
||||
github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=
|
||||
github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
|
||||
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
|
||||
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
|
||||
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
||||
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
||||
github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=
|
||||
github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q=
|
||||
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
|
||||
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
|
||||
github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
|
||||
github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
|
||||
github.com/clipperhouse/displaywidth v0.10.0 h1:GhBG8WuerxjFQQYeuZAeVTuyxuX+UraiZGD4HJQ3Y8g=
|
||||
github.com/clipperhouse/displaywidth v0.10.0/go.mod h1:XqJajYsaiEwkxOj4bowCTMcT1SgvHo9flfF3jQasdbs=
|
||||
github.com/clipperhouse/uax29/v2 v2.6.0 h1:z0cDbUV+aPASdFb2/ndFnS9ts/WNXgTNNGFoKXuhpos=
|
||||
github.com/clipperhouse/uax29/v2 v2.6.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@@ -61,8 +35,6 @@ github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5Jflh
|
||||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||
github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
|
||||
github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
@@ -88,8 +60,6 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/invopop/jsonschema v0.14.0 h1:MHQqLhvpNUZfw+hM3AZDYK7jxO8FZoQeQM77g8iyZjg=
|
||||
github.com/invopop/jsonschema v0.14.0/go.mod h1:ygm6C2EaVNMBDPpaPlnOA2pFAxBnxGjFlMZABxm9n2I=
|
||||
github.com/jandedobbeleer/clipboard v0.1.4-1 h1:rJehm5W0a3hvjcxyB3snqLBV4yvMBBc12JyMP7ngNQw=
|
||||
github.com/jandedobbeleer/clipboard v0.1.4-1/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
@@ -99,30 +69,18 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4=
|
||||
github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k=
|
||||
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
||||
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
||||
github.com/mattn/go-runewidth v0.0.27 h1:Feg/Oou5zI/wnpgDF6omIU0OokC9GxLC/WRknhVlIR0=
|
||||
github.com/mattn/go-runewidth v0.0.27/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
|
||||
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
||||
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
|
||||
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
|
||||
github.com/pb33f/ordered-map/v2 v2.3.1 h1:5319HDO0aw4DA4gzi+zv4FXU9UlSs3xGZ40wcP1nBjY=
|
||||
github.com/pb33f/ordered-map/v2 v2.3.1/go.mod h1:qxFQgd0PkVUtOMCkTapqotNgzRhMPL7VvaHKbd1HnmQ=
|
||||
github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY=
|
||||
@@ -131,13 +89,9 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
|
||||
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
|
||||
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
github.com/shirou/gopsutil/v4 v4.26.6 h1:Mzr/npDtQC/xpeEuQKHZt8Zo9CmPvhTj8nkR8w5TLDs=
|
||||
@@ -196,7 +150,6 @@ golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||
|
||||
@@ -30,7 +30,7 @@ your terminal emulator to use it.
|
||||
}>
|
||||
<TabItem value="oh-my-posh">
|
||||
|
||||
Oh My Posh has a CLI to help you select and install a [Nerd Font][nerdfonts]:
|
||||
Oh My Posh has a CLI to install a [Nerd Font][nerdfonts]:
|
||||
|
||||
:::info
|
||||
When running as root/administrator, the fonts will be installed system-wide.
|
||||
@@ -39,14 +39,26 @@ By default, Oh My Posh installs the `.ttf` version of the font in case multiple
|
||||
:::
|
||||
|
||||
```bash
|
||||
oh-my-posh font install
|
||||
oh-my-posh font install meslo
|
||||
```
|
||||
|
||||
This will present a list of Nerd Font libraries, from which you can select `Meslo`, which includes the
|
||||
`Meslo LGM NF` font we recommend. Note that you can also install it directly via:
|
||||
We recommend `Meslo`, which includes the `Meslo LGM NF` font. To see every font you can install:
|
||||
|
||||
```bash
|
||||
oh-my-posh font install meslo
|
||||
oh-my-posh font list
|
||||
```
|
||||
|
||||
That prints one name per line, so you can search it:
|
||||
|
||||
```bash
|
||||
oh-my-posh font list | grep -i mono
|
||||
```
|
||||
|
||||
You can also install straight from a URL or a local zip file:
|
||||
|
||||
```bash
|
||||
oh-my-posh font install https://example.com/font.zip
|
||||
oh-my-posh font install ./CascadiaCode.zip
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
@@ -59,10 +59,10 @@ curl -s https://ohmyposh.dev/install.sh | bash -s
|
||||
Oh My Posh themes use glyphs and icons from Nerd Fonts. Install a Nerd Font with:
|
||||
|
||||
```bash
|
||||
oh-my-posh font install
|
||||
oh-my-posh font install meslo
|
||||
```
|
||||
|
||||
Recommended font: Meslo LGM NF. Set the font in your terminal emulator after installation.
|
||||
List every installable font with `oh-my-posh font list`. Recommended font: Meslo LGM NF. Set the font in your terminal emulator after installation.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -30,10 +30,11 @@ description: "Install, configure, or troubleshoot Oh My Posh/ohmyposh: shell ini
|
||||
3. **Install a Nerd Font** — required for icons and glyphs:
|
||||
|
||||
```bash
|
||||
oh-my-posh font install
|
||||
oh-my-posh font install meslo
|
||||
```
|
||||
|
||||
Recommended: **Meslo LGM NF**. Set it in the terminal emulator's font settings after installing.
|
||||
`oh-my-posh font list` prints every installable font. Recommended: **Meslo LGM NF**.
|
||||
Set it in the terminal emulator's font settings after installing.
|
||||
|
||||
4. **Customize the prompt** → see [configuration](/skills/ohmyposh/configuration.md)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user