diff --git a/cmd/org/main.go b/cmd/org/main.go index c36a939..c11e059 100644 --- a/cmd/org/main.go +++ b/cmd/org/main.go @@ -1,8 +1,10 @@ package main import ( + "bufio" "flag" "fmt" + "io" "os" "path/filepath" @@ -15,13 +17,43 @@ import ( func main() { var filePath string var multiMode bool + var captureMode bool flag.BoolVar(&multiMode, "multi", false, "Load all org files in current directory as top-level items") flag.BoolVar(&multiMode, "m", false, "Load all org files in current directory (shorthand)") + flag.BoolVar(&captureMode, "capture", false, "Start in capture mode") + flag.BoolVar(&captureMode, "c", false, "Start in capture mode (shorthand)") flag.Parse() - // Check for positional argument - if filePath == "" && len(flag.Args()) > 0 { - filePath = flag.Args()[0] + // Check for positional argument or capture text + var captureText string + if len(flag.Args()) > 0 { + if captureMode { + // First argument is capture text when in capture mode + captureText = flag.Args()[0] + // Second argument (if present) is the file path + if len(flag.Args()) > 1 { + filePath = flag.Args()[1] + } + } else { + // First argument is file path in normal mode + filePath = flag.Args()[0] + } + } + + // Check if input is being piped + stat, _ := os.Stdin.Stat() + if (stat.Mode() & os.ModeCharDevice) == 0 { + // Data is being piped to stdin + reader := bufio.NewReader(os.Stdin) + pipedText, err := io.ReadAll(reader) + if err == nil && len(pipedText) > 0 { + captureMode = true + captureText = string(pipedText) + // If no file path was provided via args, check if last arg could be a path + if filePath == "" && len(flag.Args()) > 0 { + filePath = flag.Args()[0] + } + } } // Load configuration @@ -81,7 +113,7 @@ func main() { } // Run the UI - if err := ui.RunUI(orgFile, cfg); err != nil { + if err := ui.RunUI(orgFile, cfg, captureMode, captureText); err != nil { fmt.Fprintf(os.Stderr, "Error running UI: %v\n", err) os.Exit(1) } diff --git a/internal/ui/app.go b/internal/ui/app.go index 3b89bc8..c139fe3 100644 --- a/internal/ui/app.go +++ b/internal/ui/app.go @@ -55,7 +55,7 @@ type uiModel struct { captureCursor int // Store cursor position when entering capture mode } -func InitialModel(orgFile *model.OrgFile, cfg *config.Config) uiModel { +func InitialModel(orgFile *model.OrgFile, cfg *config.Config, captureMode bool, captureText string) uiModel { ta := textarea.New() ta.Placeholder = "Enter notes here (code blocks supported)..." ta.ShowLineNumbers = false @@ -67,10 +67,16 @@ func InitialModel(orgFile *model.OrgFile, cfg *config.Config) uiModel { h := help.New() h.ShowAll = false + mode := modeList + if captureMode { + mode = modeCapture + ti.SetValue(strings.TrimSpace(captureText)) + } + return uiModel{ orgFile: orgFile, cursor: 0, - mode: modeList, + mode: mode, help: h, keys: newKeyMapFromConfig(cfg), styles: newStyleMapFromConfig(cfg), @@ -81,6 +87,9 @@ func InitialModel(orgFile *model.OrgFile, cfg *config.Config) uiModel { } func (m uiModel) Init() tea.Cmd { + if m.mode == modeCapture { + return textinput.Blink + } return nil } @@ -140,8 +149,12 @@ func (m *uiModel) updateScrollOffset(availableHeight int) { } // RunUI starts the terminal UI -func RunUI(orgFile *model.OrgFile, cfg *config.Config) error { - p := tea.NewProgram(InitialModel(orgFile, cfg), tea.WithAltScreen()) +func RunUI(orgFile *model.OrgFile, cfg *config.Config, captureMode bool, captureText string) error { + m := InitialModel(orgFile, cfg, captureMode, captureText) + if captureMode { + m.textinput.Focus() + } + p := tea.NewProgram(m, tea.WithAltScreen()) _, err := p.Run() return err }