diff --git a/cmd/modo/main.go b/cmd/modo/main.go index 5c7e788..53ed490 100644 --- a/cmd/modo/main.go +++ b/cmd/modo/main.go @@ -14,13 +14,13 @@ func main() { slog.Error("something went wrong", "error", err) return } - defer f.Close() - lineEndingLen, err := parser.GetLineEndingLen(f) + defer f.File.Close() + lineEndingLen, err := parser.GetLineEndingLen(f.File) if err != nil { slog.Error("something went wrong", "error", err) return } - todos, err := parser.ParseTodos(f, lineEndingLen) + todos, err := parser.ParseTodos(f.File, lineEndingLen, f.PreserveIndent) if err != nil { slog.Error("something went wrong", "error", err) } @@ -28,5 +28,5 @@ func main() { slog.Error("no todos found") return } - renderer.NewRenderer(todos, f).Render() + renderer.NewRenderer(todos, f.File).Render() } diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 43a3600..68e41c8 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -2,6 +2,7 @@ package cli import ( "errors" + "flag" "fmt" "os" ) @@ -14,11 +15,11 @@ var ( ) const ( - Version = "0.0.6" + Version = "0.0.7" Author = "elliot40404" Name = "modo" Desc = "Modo is a simple cli app that lets you interact any text file that contains checkboxes in the markdown format." - Example = "modo " + Example = "modo " ) func help() { @@ -30,38 +31,61 @@ Usage: %s Options: - -h, --help Show this help message - -v, --version Show version information + -h, --help Show this help message + -v, --version Show version information + -p, --preserve-indent Preserve indentation of the checkboxes Examples: %s `, Name, Version, Desc, Example, Example) } -func ParseArgs() (*os.File, error) { - if len(os.Args) < 2 { +type ParsedArgs struct { + PreserveIndent bool + File *os.File +} + +func ParseArgs() (ParsedArgs, error) { + helpFlag := flag.Bool("help", false, "Show help message") + versionFlag := flag.Bool("v", false, "Show version information") + versionLongFlag := flag.Bool("version", false, "Show version information") + indentFlag := flag.Bool("preserve-indent", false, "preserve original identations") + indentLongFlag := flag.Bool("p", false, "preserve original identations") + + flag.Usage = help + + flag.Parse() + + if *helpFlag { help() - os.Exit(1) + os.Exit(0) } - arg := os.Args[1] - if arg == "-h" || arg == "--help" { - help() - os.Exit(1) - } - if arg == "-v" || arg == "--version" { + + if *versionFlag || *versionLongFlag { fmt.Printf("%s %s\n", Name, Version) + os.Exit(0) + } + + if flag.NArg() < 1 { + help() os.Exit(1) } + + arg := flag.Arg(0) + fi, err := os.Stat(arg) if err != nil { - return nil, ErrFileNotExist + return ParsedArgs{}, ErrFileNotExist } if fi.IsDir() { - return nil, ErrNotAFile + return ParsedArgs{}, ErrNotAFile } f, err := os.OpenFile(arg, os.O_RDWR, 0o644) if err != nil { - return nil, ErrFileOpen + return ParsedArgs{}, ErrFileOpen } - return f, nil + return ParsedArgs{ + PreserveIndent: *indentFlag || *indentLongFlag, + File: f, + }, nil } diff --git a/internal/parser/parser.go b/internal/parser/parser.go index 70d5d10..de92571 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -34,13 +34,13 @@ func (t *Todo) ToggleChecked(f *os.File) { } } -func ParseTodos(f io.Reader, lineEndingLen int) ([]Todo, error) { +func ParseTodos(f io.Reader, lineEndingLen int, preserveIndent bool) ([]Todo, error) { todos := make([]Todo, 0) scanner := bufio.NewScanner(f) offset := int64(0) for scanner.Scan() { line := scanner.Text() - if todo, ok := ParseTodo(line, offset); ok { + if todo, ok := ParseTodo(line, offset, preserveIndent); ok { todos = append(todos, todo) } offset += int64(len(line) + lineEndingLen) @@ -73,14 +73,19 @@ func GetLineEndingLen(f *os.File) (int, error) { return lineEndingLen, nil } -func ParseTodo(line string, offset int64) (Todo, bool) { +func ParseTodo(line string, offset int64, preserveIndent bool) (Todo, bool) { ogLine := line - line = strings.Trim(line, " ") + line = strings.TrimSpace(line) if strings.HasPrefix(line, "- [ ]") || strings.HasPrefix(strings.ToLower(line), "- [x]") { + content := strings.Split(line, "] ")[1] + if preserveIndent { + content = strings.Replace(ogLine, "- [ ]", "", 1) + content = strings.Replace(content, "- [x]", "", 1) + } todo := Todo{ Line: ogLine, Done: strings.Contains(strings.ToLower(line), "[x]"), - Content: strings.Split(line, "] ")[1], + Content: content, Offset: offset, } return todo, true