Skip to content

Commit

Permalink
batman
Browse files Browse the repository at this point in the history
  • Loading branch information
elliot40404 committed Jan 5, 2025
0 parents commit e100a9a
Show file tree
Hide file tree
Showing 573 changed files with 261,343 additions and 0 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: goreleaser

on:
push:
tags:
- '*'

permissions:
contents: write

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: stable
- uses: golangci/golangci-lint-action@v3
with:
version: latest
args: --timeout=5m
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: git fetch --force --tags
- uses: actions/setup-go@v4
with:
go-version: stable
- uses: goreleaser/goreleaser-action@v4
with:
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bin/
example.md
dist/
58 changes: 58 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
run:
concurrency: 8
timeout: 30m
issues-exit-code: 1
tests: true
build-tags:
- integration
modules-download-mode: readonly
allow-parallel-runners: false

linters:
fast: false

enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- contextcheck
- durationcheck
- errcheck
- errname
- errorlint
- gocritic
- godot
- gofmt
- gofumpt
- goimports
- gomoddirectives
- gosec
- gosimple
- govet
- ineffassign
- misspell
- nakedret
- nilerr
- nilnil
- noctx
- nolintlint
- prealloc
- predeclared
- promlinter
- reassign
- revive
- rowserrcheck
- sqlclosecheck
- staticcheck
- stylecheck
- tagliatelle
- tenv
- testableexamples
- thelper
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- wastedassign
29 changes: 29 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com

# The lines below are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/need to use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

version: 2

before:
hooks:
- go mod tidy

builds:
- main: ./cmd/modo
id: modo
binary: modo
env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
goarch:
- "amd64"

archives:
- format: binary
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# MODO

> Modo is a simple cli app that lets you interact any text file that contains checkboxes in the markdown format.
## Why

I usually write my notes in markdown format and I like lists.

## Installation

```bash
go install github.com/elliot40404/modo@latest
```

## Usage

```bash
modo <file>
```

## License

MIT
30 changes: 30 additions & 0 deletions cmd/modo/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"log/slog"

tea "github.com/charmbracelet/bubbletea"

"github.com/elliot40404/modo/internal/cli"
"github.com/elliot40404/modo/internal/renderer"
"github.com/elliot40404/modo/internal/todo"
)

func main() {
f, err := cli.ParseArgs()
if err != nil {
slog.Error("something went wrong", "error", err)
return
}
defer f.Close()
todos, err := todo.ParseTodos(f)
if err != nil {
slog.Error("something went wrong", "error", err)
}
p := tea.NewProgram(renderer.InitialModel(todos, f))
_, err = p.Run()
if err != nil {
slog.Error("something went wrong", "error", err)
return
}
}
24 changes: 24 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module github.com/elliot40404/modo

go 1.22.1

require github.com/charmbracelet/bubbletea v1.2.4

require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/lipgloss v1.0.0 // indirect
github.com/charmbracelet/x/ansi v0.4.5 // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.3.8 // indirect
)
37 changes: 37 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/charmbracelet/bubbletea v1.2.4 h1:KN8aCViA0eps9SCOThb2/XPIlea3ANJLUkv3KnQRNCE=
github.com/charmbracelet/bubbletea v1.2.4/go.mod h1:Qr6fVQw+wX7JkWWkVyXYk/ZUQ92a6XNekLXa3rR18MM=
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSexTdRM=
github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
67 changes: 67 additions & 0 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package cli

import (
"errors"
"fmt"
"os"
)

var (
ErrNoInputFile = errors.New("no input file provided")
ErrFileNotExist = errors.New("file does not exist")
ErrNotAFile = errors.New("not a file")
ErrFileOpen = errors.New("error opening file")
)

const (
Version = "0.0.1"
Author = "elliot40404<avishek40404@gmail.com>"
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 <file>"
)

func help() {
fmt.Printf(`%s %s
%s
Usage:
%s %s
Options:
-h, --help Show this help message
-v, --version Show version information
Examples:
%s
`, Name, Version, Desc, Name, Example, Example)
}

func ParseArgs() (*os.File, error) {
if len(os.Args) < 2 {
help()
os.Exit(1)
}
arg := os.Args[1]
if arg == "-h" || arg == "--help" {
help()
os.Exit(1)
}
if arg == "-v" || arg == "--version" {
fmt.Printf("%s %s\n", Name, Version)
os.Exit(1)
}
fi, err := os.Stat(arg)
if err != nil {
return nil, ErrFileNotExist
}
if fi.IsDir() {
return nil, ErrNotAFile
}
f, err := os.OpenFile(arg, os.O_RDWR, 0o644)
if err != nil {
return nil, ErrFileOpen
}
return f, nil
}
77 changes: 77 additions & 0 deletions internal/renderer/renderer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package renderer

import (
"fmt"
"os"

tea "github.com/charmbracelet/bubbletea"

"github.com/elliot40404/modo/internal/todo"
)

type Model struct {
fd *os.File
choices []todo.Todo
cursor int
selected map[int]struct{}
}

func (m Model) Init() tea.Cmd {
return nil
}

func InitialModel(todos []todo.Todo, fd *os.File) Model {
selected := make(map[int]struct{})
for i, todo := range todos {
if todo.Done {
selected[i] = struct{}{}
}
}
return Model{
choices: todos,
selected: selected,
fd: fd,
}
}

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if msg, ok := msg.(tea.KeyMsg); ok {
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
case "up", "k":
if m.cursor > 0 {
m.cursor--
}
case "down", "j":
if m.cursor < len(m.choices)-1 {
m.cursor++
}
case "enter", " ":
_, ok := m.selected[m.cursor]
m.choices[m.cursor].ToggleChecked(m.fd)
if ok {
delete(m.selected, m.cursor)
} else {
m.selected[m.cursor] = struct{}{}
}
}
}
return m, nil
}

func (m Model) View() string {
s := ""
for i, choice := range m.choices {
cursor := " "
if m.cursor == i {
cursor = ">"
}
checked := " "
if _, ok := m.selected[i]; ok {
checked = "x"
}
s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice.Content)
}
return s
}
Loading

0 comments on commit e100a9a

Please sign in to comment.