nt

A sensible note-taking program
git clone git://git.laack.co/nt.git
Log | Files | Refs | README

main.go (2970B)


      1 package main
      2 
      3 import (
      4 	"encoding/json"
      5 	"errors"
      6 	// "fmt"
      7 	"log"
      8 	"os"
      9 	"os/exec"
     10 	"path"
     11 	"strconv"
     12 	"strings"
     13 
     14 	"github.com/gdamore/tcell/v2"
     15 	"github.com/rivo/tview"
     16 )
     17 
     18 type Config struct {
     19 	NoteDirs []string `json:"noteDirs"`
     20 	TodoFiles []string `json:"todoFiles"`
     21 }
     22 
     23 func readConfig() Config {
     24 
     25 	configBase, err := os.UserConfigDir()
     26 
     27 	if err != nil {
     28 		log.Fatal(err)
     29 	}
     30 
     31 	appConfigDir := configBase + "/nt/"
     32 
     33 	// fmt.Println(configBase)
     34 	// fmt.Println(appConfigDir)
     35 
     36 	err = os.MkdirAll(appConfigDir, 0755)
     37 
     38 	if err != nil {
     39 		log.Fatal(err)
     40 	}
     41 
     42 	configFilePath := appConfigDir + "config.json"
     43 
     44 	configuration := &Config{
     45 		NoteDirs: []string{"$HOME/.notes"},
     46 		TodoFiles: []string{"$HOME/.todo/main.md"},
     47 	}
     48 
     49 	if _, err := os.Stat(configFilePath); !errors.Is(err, os.ErrNotExist) {
     50 		configFileData, err := os.ReadFile(configFilePath)
     51 
     52 		if err != nil {
     53 			log.Fatal(err)
     54 		}
     55 		err = json.Unmarshal(configFileData, configuration)
     56 		if err != nil {
     57 			log.Fatal(err)
     58 		}
     59 	} else {
     60 		configBytes , err := json.MarshalIndent(configuration, "", "	")
     61 		if err != nil {
     62 			log.Fatal(err)
     63 		}
     64 
     65 		os.WriteFile(configFilePath, configBytes, 0644)
     66 
     67 	}
     68 
     69 	for idx, noteDir := range configuration.NoteDirs {
     70 		configuration.NoteDirs[idx] = os.ExpandEnv(noteDir)
     71 		os.MkdirAll(configuration.NoteDirs[idx], 0755)
     72 	}
     73 
     74 	for idx, noteDir := range configuration.TodoFiles {
     75 		configuration.TodoFiles[idx] = os.ExpandEnv(noteDir)
     76 		os.MkdirAll(path.Dir(configuration.TodoFiles[idx]), 0755)
     77 	}
     78 
     79 	return *configuration
     80 }
     81 
     82 var (
     83 	app *tview.Application
     84 	mainArea *tview.Flex
     85 	selectionOptions []string
     86 	conf Config
     87 )
     88 
     89 func repaint() {
     90 
     91 	mainArea = tview.NewFlex().SetDirection(tview.FlexRow)
     92 	mainArea.SetBorder(true)
     93 
     94 	selections := conf.TodoFiles
     95 
     96 	selectionOptions = []string{}
     97 	
     98 	todoHeader := tview.NewTextView()
     99 	todoHeader.SetText("Todo:")
    100 	mainArea.AddItem(todoHeader, 1, 1, true)
    101 
    102 	for idx, selection := range selections {
    103 		sel := tview.NewTextView()
    104 		sel.SetText(strconv.Itoa(idx) + " " + selection)
    105 		mainArea.AddItem(sel, 1, 1, true)
    106 		selectionOptions = append(selectionOptions, selection)
    107 	}
    108 
    109 }
    110 
    111 func main() {
    112 
    113 	// TODO: Ensure all configuration fields are filled in, always in the config
    114 
    115 	conf = readConfig()
    116 	// fmt.Println(conf)
    117 
    118 	app = tview.NewApplication()
    119 
    120 	repaint()
    121 
    122 	mainArea.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
    123 		r := event.Rune()
    124 
    125 		num, err := strconv.Atoi(string(r))
    126 
    127 		if err == nil && num < len(selectionOptions){
    128 			app.Suspend(func() {
    129 
    130 				editor := os.Getenv("EDITOR")
    131 
    132 				if strings.Compare(editor, "") == 0 {
    133 					editor = "vim"
    134 				}
    135 
    136 				cmd := exec.Command(editor, selectionOptions[num])
    137 				cmd.Stdin = os.Stdin
    138 				cmd.Stdout = os.Stdout
    139 				cmd.Stderr = os.Stderr
    140 				if err := cmd.Run(); err != nil {
    141 					log.Printf("nvim error: %v", err)
    142 				}
    143 				cmd.Wait()
    144 			})
    145 		}
    146 
    147 
    148 		repaint()
    149 
    150 		return event
    151 	})
    152 
    153 
    154 	app.SetRoot(mainArea, true).SetFocus(mainArea)
    155 
    156 	err := app.Run()
    157 
    158 	if err != nil {
    159 		panic(err)
    160 	}
    161 
    162 }