diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b4ceeaf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/zet diff --git a/build b/build new file mode 100755 index 0000000..af2e46b --- /dev/null +++ b/build @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -euo pipefail + +echo "Building..." + +go build -o zet main.go + +echo "Done." diff --git a/cmd/root.go b/cmd/root.go index 2a6f443..f086cd2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -37,6 +37,8 @@ func Execute() { } func init() { + rootCmd.AddCommand(titlesCmd) + // Here you will define your flags and configuration settings. // Cobra supports persistent flags, which, if defined here, // will be global for your application. diff --git a/cmd/titles.go b/cmd/titles.go new file mode 100644 index 0000000..175ac02 --- /dev/null +++ b/cmd/titles.go @@ -0,0 +1,26 @@ +package cmd + +import ( + "github.com/spf13/cobra" + + "code.oliverdavies.uk/opdavies/cmd-zet/internal/lib" +) + +var titlesCmd = &cobra.Command{ + Use: "titles", + Aliases: []string{"t"}, + Short: "A brief description of your command", + Long: `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + Run: func(cmd *cobra.Command, args []string) { + zetDir := "/home/opdavies/Documents/zet" + + zets := lib.GetAllZets(zetDir) + + lib.ParseZetList(zets) + }, +} diff --git a/go.mod b/go.mod index 466a14f..bcaf3a4 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module zet +module code.oliverdavies.uk/opdavies/cmd-zet go 1.24.6 diff --git a/internal/lib/git.go b/internal/lib/git.go new file mode 100644 index 0000000..eda5e53 --- /dev/null +++ b/internal/lib/git.go @@ -0,0 +1,12 @@ +package lib + +import "os/exec" + +func execGitCommand(dir string, parts ...string) (string, error) { + args := append([]string{"-C", dir}, parts...) + command := exec.Command("git", args...) + + output, err := command.CombinedOutput() + + return string(output), err +} diff --git a/internal/lib/lib.go b/internal/lib/lib.go new file mode 100644 index 0000000..a10699c --- /dev/null +++ b/internal/lib/lib.go @@ -0,0 +1,93 @@ +package lib + +import ( + "bufio" + "fmt" + "log" + "os" + "path" + "regexp" + "sort" + "strconv" + "strings" +) + +func GetAllZets(dir string) []int { + zets, err := execGitCommand(dir, "ls-files") + + if err != nil { + log.Println(err) + } + + re := regexp.MustCompile(`[0-9]+`) + matches := re.FindAllString(zets, -1) + + sort.Strings(matches) + + ids := make(map[int]struct{}) + for _, id := range matches { + num, err := strconv.Atoi(id) + + if err == nil { + ids[num] = struct{}{} + } + } + + var sorted []int + for num := range ids { + sorted = append(sorted, num) + } + + sort.Ints(sorted) + + return sorted +} + +func ParseZetList(ids []int) []string { + var lines []string + + green := "\033[32m" + reset := "\033[0m" + + for _, num := range ids { + line := fmt.Sprintf("%s%s%s %s", green, strconv.Itoa(num), reset, getTitle(num)) + + fmt.Println(line) + + lines = append(lines, line) + } + + return lines +} + +func getTitle(id int) string { + return getTitleFromFile(path.Join(strconv.Itoa(id), "index.adoc")) +} + +func getTitleFromFile(filePath string) string { + filePath = path.Join("/home/opdavies/Documents/zet", filePath) + + file, err := os.Open(filePath) + + if err != nil { + fmt.Println("Error opening file:", err) + + return "" + } + + defer file.Close() + + scanner := bufio.NewScanner(file) + + if scanner.Scan() { + text := scanner.Text() + + return strings.TrimPrefix(text, "= ") + } + + if err := scanner.Err(); err != nil { + fmt.Println("Error reading file:", err) + } + + return "" +} diff --git a/main.go b/main.go index 55d8744..7b82f30 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ package main -import "zet/cmd" +import "code.oliverdavies.uk/opdavies/cmd-zet/cmd" func main() { cmd.Execute() diff --git a/watch b/watch new file mode 100755 index 0000000..fc894da --- /dev/null +++ b/watch @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -euo pipefail + +onchange "**/*.go" "./build && echo "" && ./zet $*" diff --git a/zet b/zet deleted file mode 100755 index 19633c4..0000000 --- a/zet +++ /dev/null @@ -1,244 +0,0 @@ -#!/usr/bin/env bash - -set -o pipefail - -IFS= read -rd '' USAGE < "$ZID/index.adoc" - edit_file "$ZID/index.adoc" - on_save "$ZID" -} - -delete_zettel() { - [[ -d "$ZID" ]] && rm -fr "$ZID" - commit_zettel "$ZID" -} - -edit_file() { - "$EDITOR" "$1" -} - -edit_zet() { - edit_file "$1/index.adoc" - on_save "$1" -} - -generate_links() { - echo "$1" | while IFS= read -r line; do - id="${line%% *}" - title="${line#* }" - echo "* link:../${id}/index.adoc[${title}]" - done -} - -get_latest_zettel() { - find . -maxdepth 1 -type d -name '[0-9]*' -printf '%f\n' | sort -nr | head -n 1 -} - -get_title() { - get_title_from_file "$1/index.adoc" -} - -get_title_from_file() { - head -n 1 "$1" | sed -e 's/^[#=] //' -} - -main() { - case "$1" in - create | new | c | n) - shift 1 - cmd_create "$@" - ;; - - edit | e) - shift 1 - cmd_edit "$@" - ;; - - help | h) - show_usage - ;; - - id) - shift 1 - cmd_id "$@" - ;; - - latest) - ZID="$(get_latest_zettel)" - edit_zet "$ZID" - ;; - - links | l) - shift 1 - cmd_links "$@" - ;; - - view | v) - shift 1 - cmd_view "$@" - ;; - - *) - cmd_search "$@" - ;; - esac -} - -new_zid() { - EXISTING_ZETTELS=$(find . -maxdepth 1 -type d -regex './[0-9]+' | wc -l) - - echo $((EXISTING_ZETTELS + 1)) -} - -on_save() { - ZID="$1" - - if [[ -s "$ZID/index.adoc" ]]; then - TITLE=$(get_title "$ZID") - commit_zettel "$ZID" "$TITLE" - else - echo "Deleting empty zettel: $ZID" - delete_zettel "$ZID" - fi -} - -parse_zet_list() { - ZET_LIST=() - - while IFS= read -r ZID; do - TITLE=$(get_title "$ZID") - ZET_LIST+=("$ZID $TITLE") - done -} - -search_zettel() { - if [[ "$*" == "latest" ]] || [[ "$*" == "l" ]]; then - get_latest_zettel - return - fi - - QUERY="$*" - - grep_args=("--extended-regexp") - [[ "$QUERY" != "" ]] && grep_args+=("--word-regex") - - git grep -i --name-only "${grep_args[@]}" "$QUERY" | grep -o -E '[0-9]+' | sort -un -} - -select_zet() { - if [[ "${#ZET_LIST[@]}" == 0 ]]; then - echo "No zettels to select" - exit 1 - fi - - if [[ "${#ZET_LIST[@]}" == 1 ]]; then - SELECTED_ZET=$(awk '{ print $1 }' <<<"${ZET_LIST[0]}") - return - fi - - selector - - if [[ -z "$SELECTED_ZET" ]]; then - echo "No zet selected" - exit 1 - fi -} - -selector() { - ITEM=$(printf "%s\n" "${ZET_LIST[@]}" | fzf --prompt="Select a zet: ") - - SELECTED_ZET=$(awk '{ print $1 }' <<< "$ITEM") -} - -show_usage() { - echo "$USAGE" -} - -view_zettel() { - cat "$1/index.adoc" -} - -(cd "$ZET_DIR" && main "$@")