mirror of
https://github.com/charmbracelet/glow.git
synced 2026-08-09 09:49:09 +02:00
feat: add new --tui / -t flag (#679)
This commit is contained in:
parent
009c37602a
commit
e03817b2cb
3 changed files with 59 additions and 15 deletions
24
main.go
24
main.go
|
|
@ -33,6 +33,7 @@ var (
|
|||
readmeNames = []string{"README.md", "README", "Readme.md", "Readme", "readme.md", "readme"}
|
||||
configFile string
|
||||
pager bool
|
||||
tui bool
|
||||
style string
|
||||
width uint
|
||||
showAllFiles bool
|
||||
|
|
@ -159,9 +160,14 @@ func validateOptions(cmd *cobra.Command) error {
|
|||
width = viper.GetUint("width")
|
||||
mouse = viper.GetBool("mouse")
|
||||
pager = viper.GetBool("pager")
|
||||
tui = viper.GetBool("tui")
|
||||
showAllFiles = viper.GetBool("all")
|
||||
preserveNewLines = viper.GetBool("preserveNewLines")
|
||||
|
||||
if pager && tui {
|
||||
return errors.New("glow: cannot use both pager and tui")
|
||||
}
|
||||
|
||||
// validate the glamour style
|
||||
style = viper.GetString("style")
|
||||
if err := validateStyle(style); err != nil {
|
||||
|
|
@ -298,7 +304,8 @@ func executeCLI(cmd *cobra.Command, src *source, w io.Writer) error {
|
|||
}
|
||||
|
||||
// display
|
||||
if pager || cmd.Flags().Changed("pager") {
|
||||
switch {
|
||||
case pager || cmd.Flags().Changed("pager"):
|
||||
pagerCmd := os.Getenv("PAGER")
|
||||
if pagerCmd == "" {
|
||||
pagerCmd = "less -r"
|
||||
|
|
@ -309,13 +316,15 @@ func executeCLI(cmd *cobra.Command, src *source, w io.Writer) error {
|
|||
c.Stdin = strings.NewReader(out)
|
||||
c.Stdout = os.Stdout
|
||||
return c.Run()
|
||||
case tui || cmd.Flags().Changed("tui"):
|
||||
return runTUI(src.URL)
|
||||
default:
|
||||
_, err = fmt.Fprint(w, out)
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = fmt.Fprint(w, out)
|
||||
return err
|
||||
}
|
||||
|
||||
func runTUI(workingDirectory string) error {
|
||||
func runTUI(path string) error {
|
||||
// Read environment to get debugging stuff
|
||||
cfg, err := env.ParseAs[ui.Config]()
|
||||
if err != nil {
|
||||
|
|
@ -327,7 +336,7 @@ func runTUI(workingDirectory string) error {
|
|||
cfg.GlamourStyle = style
|
||||
}
|
||||
|
||||
cfg.WorkingDirectory = workingDirectory
|
||||
cfg.Path = path
|
||||
cfg.ShowAllFiles = showAllFiles
|
||||
cfg.ShowLineNumbers = showLineNumbers
|
||||
cfg.GlamourMaxWidth = width
|
||||
|
|
@ -370,6 +379,7 @@ func init() {
|
|||
// "Glow Classic" cli arguments
|
||||
rootCmd.PersistentFlags().StringVar(&configFile, "config", "", fmt.Sprintf("config file (default %s)", viper.GetViper().ConfigFileUsed()))
|
||||
rootCmd.Flags().BoolVarP(&pager, "pager", "p", false, "display with pager")
|
||||
rootCmd.Flags().BoolVarP(&tui, "tui", "t", false, "display with tui")
|
||||
rootCmd.Flags().StringVarP(&style, "style", "s", styles.AutoStyle, "style name or JSON path")
|
||||
rootCmd.Flags().UintVarP(&width, "width", "w", 0, "word-wrap at width (set to 0 to disable)")
|
||||
rootCmd.Flags().BoolVarP(&showAllFiles, "all", "a", false, "show system files and directories (TUI-mode only)")
|
||||
|
|
@ -379,6 +389,8 @@ func init() {
|
|||
_ = rootCmd.Flags().MarkHidden("mouse")
|
||||
|
||||
// Config bindings
|
||||
_ = viper.BindPFlag("pager", rootCmd.Flags().Lookup("pager"))
|
||||
_ = viper.BindPFlag("tui", rootCmd.Flags().Lookup("tui"))
|
||||
_ = viper.BindPFlag("style", rootCmd.Flags().Lookup("style"))
|
||||
_ = viper.BindPFlag("width", rootCmd.Flags().Lookup("width"))
|
||||
_ = viper.BindPFlag("debug", rootCmd.Flags().Lookup("debug"))
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ type Config struct {
|
|||
EnableMouse bool
|
||||
PreserveNewLines bool
|
||||
|
||||
// Which directory should we start from?
|
||||
WorkingDirectory string
|
||||
// Working directory or file path
|
||||
Path string
|
||||
|
||||
// For debugging the UI
|
||||
HighPerformancePager bool `env:"GLOW_HIGH_PERFORMANCE_PAGER" envDefault:"true"`
|
||||
|
|
|
|||
46
ui/ui.go
46
ui/ui.go
|
|
@ -144,17 +144,50 @@ func newModel(cfg Config) tea.Model {
|
|||
cfg: cfg,
|
||||
}
|
||||
|
||||
return model{
|
||||
m := model{
|
||||
common: &common,
|
||||
state: stateShowStash,
|
||||
pager: newPagerModel(&common),
|
||||
stash: newStashModel(&common),
|
||||
}
|
||||
|
||||
info, err := os.Stat(cfg.Path)
|
||||
if err != nil {
|
||||
log.Error("unable to stat file", "file", m.common.cfg.Path, "error", err)
|
||||
m.fatalErr = err
|
||||
return m
|
||||
}
|
||||
if info.IsDir() {
|
||||
m.state = stateShowStash
|
||||
} else {
|
||||
cwd, _ := os.Getwd()
|
||||
m.state = stateShowDocument
|
||||
m.pager.currentDocument = markdown{
|
||||
localPath: cfg.Path,
|
||||
Note: stripAbsolutePath(cfg.Path, cwd),
|
||||
Modtime: info.ModTime(),
|
||||
}
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (m model) Init() tea.Cmd {
|
||||
cmds := []tea.Cmd{m.stash.spinner.Tick}
|
||||
cmds = append(cmds, findLocalFiles(*m.common))
|
||||
|
||||
switch m.state {
|
||||
case stateShowStash:
|
||||
cmds = append(cmds, findLocalFiles(*m.common))
|
||||
case stateShowDocument:
|
||||
content, err := os.ReadFile(m.common.cfg.Path)
|
||||
if err != nil {
|
||||
log.Error("unable to read file", "file", m.common.cfg.Path, "error", err)
|
||||
return func() tea.Msg { return errMsg{err} }
|
||||
}
|
||||
body := string(utils.RemoveFrontmatter(content))
|
||||
cmds = append(cmds, renderWithGlamour(m.pager, body))
|
||||
}
|
||||
|
||||
return tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
|
|
@ -314,7 +347,7 @@ func findLocalFiles(m commonModel) tea.Cmd {
|
|||
return func() tea.Msg {
|
||||
log.Info("findLocalFiles")
|
||||
var (
|
||||
cwd = m.cfg.WorkingDirectory
|
||||
cwd = m.cfg.Path
|
||||
err error
|
||||
)
|
||||
|
||||
|
|
@ -380,17 +413,16 @@ func waitForStatusMessageTimeout(appCtx applicationContext, t *time.Timer) tea.C
|
|||
// document. Note that we could be doing things like checking if the file is
|
||||
// a directory, but we trust that gitcha has already done that.
|
||||
func localFileToMarkdown(cwd string, res gitcha.SearchResult) *markdown {
|
||||
md := &markdown{
|
||||
return &markdown{
|
||||
localPath: res.Path,
|
||||
Note: stripAbsolutePath(res.Path, cwd),
|
||||
Modtime: res.Info.ModTime(),
|
||||
}
|
||||
|
||||
return md
|
||||
}
|
||||
|
||||
func stripAbsolutePath(fullPath, cwd string) string {
|
||||
return strings.ReplaceAll(fullPath, cwd+string(os.PathSeparator), "")
|
||||
path, _ := filepath.Rel(cwd, fullPath)
|
||||
return path
|
||||
}
|
||||
|
||||
// Lightweight version of reflow's indent function.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue