Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,21 @@ func main() {
showVersionInfo()
return

case "init":
tui.RunInitWizard()
return

case "help", "-help", "--help", "-h":
printHelp()
return
}
}

if !tui.ConfigFound {
fmt.Println("No tuido configuration found. Run `tuido init` to set up.")
os.Exit(1)
}

var showVersion = flag.Bool("version", false, "show version and platform information")
flag.Usage = printHelp
flag.Parse()
Expand Down Expand Up @@ -117,6 +126,7 @@ Commands:
--max N Limit output to N items
create <text> Create a new todo item
add <text> Alias for create
init Create a local or global config (interactive)
version Show version and platform information
help Show this help

Expand Down
89 changes: 78 additions & 11 deletions tui/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
)
Expand Down Expand Up @@ -44,17 +45,6 @@ var runConfig config = config{
frictionThreshold: 5,
}

func adoptConfigSettings(location string) {
config := parseConfigIfExists(location)

if config != nil {
runConfig.extensions = append(runConfig.extensions, config.extensions...)
if config.writeto != "" {
runConfig.writeto = config.writeto
}
}
}

func parseConfigIfExists(configPath string) *config {

if config, err := os.Open(configPath); err == nil {
Expand Down Expand Up @@ -106,6 +96,83 @@ func parseConfig(file *os.File) config {
return cfg
}

func (cfg config) hasSettings() bool {
return len(cfg.extensions) > 0 || cfg.writeto != ""
}

// RunInitWizard interactively creates a local or global tuido config file.
func RunInitWizard() {
reader := bufio.NewReader(os.Stdin)

fmt.Print("Configure locally (./.tuido) or globally (~/.config/tuido.conf)? [l/g]: ")
choice, _ := reader.ReadString('\n')
isLocal := strings.ToLower(strings.TrimSpace(choice)) != "g"

var configPath, defaultWriteto string
if isLocal {
cwd, _ := os.Getwd()
configPath = filepath.Join(cwd, ".tuido")
defaultWriteto = filepath.Join(cwd, ".tuido")
} else {
cfgDir, _ := os.UserConfigDir()
configPath = filepath.Join(cfgDir, "tuido.conf")
home, _ := os.UserHomeDir()
defaultWriteto = filepath.Join(home, ".tuido")
}

fmt.Printf("Where should new items be written? [%s]: ", defaultWriteto)
writeto, _ := reader.ReadString('\n')
writeto = strings.TrimSpace(writeto)
if writeto == "" {
writeto = defaultWriteto
}

defaultExt := strings.Join(runConfig.extensions, ",")
fmt.Printf("File extensions to scan (comma-separated)? [%s]: ", defaultExt)
extInput, _ := reader.ReadString('\n')
extInput = strings.TrimSpace(extInput)
if extInput == "" {
extInput = defaultExt
}

if err := writeConfigFile(configPath, extInput, writeto); err != nil {
fmt.Printf("Error writing config to %s: %v\n", configPath, err)
os.Exit(1)
}
fmt.Printf("Config written to %s\n", configPath)
}

// writeConfigFile writes config lines to path, preserving any non-config
// content (todo items) that already exists below the config header.
func writeConfigFile(path, extensions, writeto string) error {
var itemLines []string
if f, err := os.Open(path); err == nil {
defer f.Close()
scanner := bufio.NewScanner(f)
pastConfig := false
for scanner.Scan() {
line := scanner.Text()
if !pastConfig {
parts := strings.SplitN(line, "=", 2)
if len(parts) == 2 {
continue
}
pastConfig = true
}
itemLines = append(itemLines, line)
}
}

var sb strings.Builder
sb.WriteString(fmt.Sprintf("extensions=%s\n", extensions))
sb.WriteString(fmt.Sprintf("writeto=%s\n", writeto))
for _, line := range itemLines {
sb.WriteString(line + "\n")
}

return os.WriteFile(path, []byte(sb.String()), 0644)
}

func GetConfigExtensions() []string {
return runConfig.extensions
}
Expand Down
56 changes: 36 additions & 20 deletions tui/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,61 @@ import (
"time"
)

// ConfigFound is true if a local or global config was loaded at startup.
// When false, the caller should prompt the user to run `tuido init`.
var ConfigFound bool

func init() {
rand.Seed(time.Now().Unix()) // a fresh set of tag colors on each run. Spice of life.
rand.Seed(time.Now().Unix())

home, err := os.UserHomeDir()
if err != nil {
fmt.Printf("error getting user home dir: %s", err)
}
tuidoDir := filepath.Join(home, ".tuido")
runConfig.writeto = tuidoDir
runConfig.writeto = filepath.Join(home, ".tuido")

loadFromDefaultConfigLocation()
ConfigFound = loadConfig()

// make sure the write target exists
_, err = os.Open(runConfig.writeto)
if err != nil {
err = os.Mkdir(runConfig.writeto, 0777)
if err != nil {
fmt.Printf("error creating appDirectory %s': %v\n",
runConfig.writeto, err)
fmt.Printf("error creating appDirectory %s': %v\n", runConfig.writeto, err)
}
}
}

// loadConfig loads configuration with priority: cwd .tuido > global config.
// Returns true if any config was found.
func loadConfig() bool {
cwd, err := os.Getwd()
if err == nil {
if cfg := parseConfigIfExists(filepath.Join(cwd, ".tuido")); cfg != nil && cfg.hasSettings() {
applyConfig(cfg)
return true
}
}
return loadFromDefaultConfigLocation()
}

func loadFromDefaultConfigLocation() {
func loadFromDefaultConfigLocation() bool {
cfgDir, err := os.UserConfigDir()
if err != nil {
fmt.Println("error seeking configdir")
return
return false
}
cfg := parseConfigIfExists(filepath.Join(cfgDir, "tuido.conf"))
if cfg == nil || !cfg.hasSettings() {
return false
}
applyConfig(cfg)
return true
}

cfgPath := filepath.Join(cfgDir, "tuido.conf")
cfg := parseConfigIfExists(cfgPath)

if cfg != nil {
if len(cfg.extensions) != 0 {
runConfig.extensions = cfg.extensions
}
if cfg.writeto != "" {
runConfig.writeto = cfg.writeto
}
func applyConfig(cfg *config) {
if len(cfg.extensions) != 0 {
runConfig.extensions = cfg.extensions
}
if cfg.writeto != "" {
runConfig.writeto = cfg.writeto
}
}
1 change: 0 additions & 1 deletion tui/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ func Run() {
panic(err)
}

adoptConfigSettings(filepath.Join(wrkdirStr, ".tuido"))
// [ ] read cli flags for added extensions / extension specificity

files := make(map[string]struct{})
Expand Down
Loading