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
60 changes: 60 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
.PHONY: build test run clean lint fmt vet test-verbose test-coverage install build-full all

INSTALL_DIR ?= /usr/local/bin

BINARY_NAME=loom
BUILD_DIR=bin

build:
go build -o $(BUILD_DIR)/$(BINARY_NAME) .

build-full:
@echo "Building with version information..."
@VERSION=$$(git describe --tags --abbrev=0 2>/dev/null || echo "dev"); \
COMMIT=$$(git rev-parse --short HEAD 2>/dev/null || echo "unknown"); \
DATE=$$(date -u +%Y-%m-%dT%H:%M:%SZ); \
echo "Version: $$VERSION"; \
echo "Commit: $$COMMIT"; \
echo "Date: $$DATE"; \
go build -trimpath -ldflags="-s -w -X 'main.version=$$VERSION' -X 'main.commit=$$COMMIT' -X 'main.date=$$DATE'" -o $(BUILD_DIR)/$(BINARY_NAME) .

install:
@echo "Building and installing $(BINARY_NAME)..."
@EXISTING=$$(which $(BINARY_NAME) 2>/dev/null); \
DEST=$$([ -n "$$EXISTING" ] && dirname "$$EXISTING" || echo "$(INSTALL_DIR)"); \
VERSION=$$([ -n "$(VERSION)" ] && echo "$(VERSION)" || git describe --tags --abbrev=0 2>/dev/null || echo "dev"); \
COMMIT=$$(git rev-parse --short HEAD 2>/dev/null || echo "unknown"); \
DATE=$$(date -u +%Y-%m-%dT%H:%M:%SZ); \
echo "Version: $$VERSION"; \
echo "Commit: $$COMMIT"; \
echo "Date: $$DATE"; \
go build -trimpath -ldflags="-s -w -X 'main.version=$$VERSION' -X 'main.commit=$$COMMIT' -X 'main.date=$$DATE'" -o $(BUILD_DIR)/$(BINARY_NAME) .; \
install -m 755 $(BUILD_DIR)/$(BINARY_NAME) "$$DEST/$(BINARY_NAME)"; \
echo "Installed to $$DEST/$(BINARY_NAME)"

run:
go run .

test:
go test ./...

test-verbose:
go test -v ./...

test-coverage:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html

clean:
rm -rf $(BUILD_DIR)
rm -f coverage.out coverage.html

fmt:
go fmt ./...

vet:
go vet ./...

lint: fmt vet

all: lint test build
3 changes: 1 addition & 2 deletions commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"strings"
"time"

tea "charm.land/bubbletea/v2"
"charm.land/bubbles/v2/viewport"
tea "charm.land/bubbletea/v2"
"charm.land/lipgloss/v2"
)

Expand Down Expand Up @@ -345,7 +345,6 @@ func (m *commitModel) View() tea.View {
sections = append(sections, footer)
content := lipgloss.JoinVertical(lipgloss.Left, sections...)


v := tea.NewView(content)
v.AltScreen = true
return v
Expand Down
16 changes: 4 additions & 12 deletions diffview.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ func funcRule() hlRule {
}

func goStringRule() hlRule {
return mustRule("`[^`]*`" + `|"(?:\\.|[^"\\])*"` + `|'(?:\\.|[^'\\])*'`, tokString)
return mustRule("`[^`]*`"+`|"(?:\\.|[^"\\])*"`+`|'(?:\\.|[^'\\])*'`, tokString)
}

func jsStringRule() hlRule {
return mustRule("`(?:\\.|[^`\\])*`" + `|"(?:\\.|[^"\\])*"` + `|'(?:\\.|[^'\\])*'`, tokString)
return mustRule("`(?:\\.|[^`\\])*`"+`|"(?:\\.|[^"\\])*"`+`|'(?:\\.|[^'\\])*'`, tokString)
}

func pyStringRule() hlRule {
return mustRule(`"""[\s\S]*?"""|'''[\s\S]*?'''` + `|"(?:\\.|[^"\\])*"` + `|'(?:\\.|[^'\\])*'`, tokString)
return mustRule(`"""[\s\S]*?"""|'''[\s\S]*?'''`+`|"(?:\\.|[^"\\])*"`+`|'(?:\\.|[^'\\])*'`, tokString)
}

func languageRules(lang string) []hlRule {
Expand Down Expand Up @@ -369,12 +369,6 @@ func langFromPath(path string) string {
return normalizeLang(ext)
}

// detectLangFromPath returns a language hint for syntax highlighting from
// a file path. Returns "" for unknown/unsupported extensions.
func detectLangFromPath(path string) string {
return langFromPath(path)
}

// --- ANSI reset rewriting (from matcha) ---

var resetRe = regexp.MustCompile(`\x1b\[0*m`)
Expand Down Expand Up @@ -644,10 +638,8 @@ func parseUnifiedDiff(diff string) []diffFileChange {
if curHunk != nil {
curHunk.lines = append(curHunk.lines, diffLine{kind: diffContext, text: line[1:]})
}
case strings.HasPrefix(line, "\\"):
// "\ No newline at end of file" — skip
default:
// skip other lines (index, mode, etc.)
// skip other lines (index, mode, "\ No newline", etc.)
}
}

Expand Down
6 changes: 1 addition & 5 deletions editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"strings"
"unicode/utf8"

tea "charm.land/bubbletea/v2"
"charm.land/bubbles/v2/viewport"
tea "charm.land/bubbletea/v2"
"charm.land/lipgloss/v2"
"github.com/floatpane/bubble-overlay"
)
Expand Down Expand Up @@ -73,9 +73,6 @@ func (e *editor) ensureVisible() {
e.vp.EnsureVisible(e.row, e.col, e.col+1)
}

func (e *editor) line() int { return e.row }
func (e *editor) column() int { return e.col }

// --- Editing operations ---

func (e *editor) insertRune(r rune) {
Expand Down Expand Up @@ -522,7 +519,6 @@ func insertCursorInColored(s string, col int) string {
b.WriteString(currentSGR.String())
}
i += size
visible++
// Copy the rest
b.WriteString(s[i:])
return b.String()
Expand Down
28 changes: 14 additions & 14 deletions rebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"strings"
"time"

tea "charm.land/bubbletea/v2"
"charm.land/bubbles/v2/viewport"
tea "charm.land/bubbletea/v2"
"charm.land/lipgloss/v2"
)

Expand All @@ -22,17 +22,17 @@ type rebaseItem struct {
}

type rebaseModel struct {
path string
items []rebaseItem
cursor int
width int
height int
saved bool
err error
expanded int // -1 = no item expanded, otherwise index into items
diff string
diffErr error
diffVP viewport.Model
path string
items []rebaseItem
cursor int
width int
height int
saved bool
err error
expanded int // -1 = no item expanded, otherwise index into items
diff string
diffErr error
diffVP viewport.Model
diffReady bool
}

Expand All @@ -50,7 +50,7 @@ func (m *rebaseModel) load() {
m.err = err
return
}
defer f.Close()
defer func() { _ = f.Close() }()

scanner := bufio.NewScanner(f)
for scanner.Scan() {
Expand Down Expand Up @@ -353,7 +353,7 @@ func (m *rebaseModel) View() tea.View {
action := actionStyle(it.action).Render(it.action)
hash := lipgloss.NewStyle().Foreground(lipgloss.Color("243")).Render(it.hash)

msg := it.msg
var msg string
if m.expanded == i {
msg = lipgloss.NewStyle().Bold(true).Render(it.msg)
} else {
Expand Down
8 changes: 5 additions & 3 deletions suggest.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,10 @@ func (ps *peopleStore) save() {
if err != nil {
return
}
os.MkdirAll(filepath.Dir(ps.filePath), 0755)
os.WriteFile(ps.filePath, data, 0644)
if err := os.MkdirAll(filepath.Dir(ps.filePath), 0755); err != nil {
return
}
_ = os.WriteFile(ps.filePath, data, 0644)
}

// addPerson adds a person to the store if not already present.
Expand Down Expand Up @@ -289,7 +291,7 @@ func loadCoAuthors() []coAuthor {
ps := newPeopleStore()
result := make([]coAuthor, len(ps.people))
for i, p := range ps.people {
result[i] = coAuthor{name: p.name, email: p.email}
result[i] = coAuthor(p)
}
return result
}
Expand Down
Loading