Skip to content

Commit 3d9e5ad

Browse files
committed
feat: adopt Obsidian vault formats
1 parent 178cf81 commit 3d9e5ad

File tree

8 files changed

+556
-23
lines changed

8 files changed

+556
-23
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ A simple Go CLI tool for generating note filenames based on date/time following
1515
- 📋 **Clipboard Support**: Copy generated names directly to clipboard (macOS)
1616
- 🚀 **Fast & Lightweight**: Written in Go for instant execution
1717
- 🔄 **Dual Commands**: Use as `stamp` or `nid` (Note ID)
18+
- 🧭 **Obsidian-Aware**: Automatically picks up [Daily Notes](https://help.obsidian.md/Plugins/Core+plugins/Daily+notes) and [Unique Note Creator](https://github.com/adriano-tirloni/unique-note-creator) formats when run inside a vault
1819

1920
## Quick Start
2021

@@ -163,6 +164,15 @@ counter_file: "~/.stamp/counters.json"
163164
project_start: 395
164165
```
165166
167+
### Obsidian Integration
168+
169+
When `stamp` runs inside an Obsidian vault it mirrors your existing date formats.
170+
171+
- **Vault detection**: the CLI walks up from the current working directory until it finds a `.obsidian/` folder.
172+
- **Daily Notes**: if the core plugin is enabled in `.obsidian/core-plugins.json`, `stamp` reads `daily-notes.json` (or `dailyNotes.format` within `app.json`) and translates the Moment-style string to Go's layout before emitting daily filenames.
173+
- **Unique Note Creator**: when the community plugin is enabled (or its folder exists) the tool inspects `.obsidian/plugins/unique-note-creator/data.json` for filename patterns and uses them for the default command.
174+
- **Graceful fallback**: missing files or unsupported tokens leave `stamp` on its built-in formats, and any read/parse issues are emitted as warnings on stderr without interrupting execution.
175+
166176
## Examples
167177

168178
### Daily Workflow
@@ -271,4 +281,4 @@ MIT License - see [LICENSE](LICENSE) file for details
271281

272282
## Author
273283

274-
Created by Tornike (Toto) Tvalavadze for personal note-taking workflows.
284+
Created by Tornike (Toto) Tvalavadze for personal note-taking workflows.

cmd/stamp/main.go

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import (
55
"os"
66

77
"github.com/spf13/cobra"
8+
"github.com/toto/stamp/internal/clipboard"
89
"github.com/toto/stamp/internal/config"
910
"github.com/toto/stamp/internal/counter"
1011
"github.com/toto/stamp/internal/generator"
11-
"github.com/toto/stamp/internal/clipboard"
12+
"github.com/toto/stamp/internal/obsidian"
1213
)
1314

1415
var (
@@ -18,17 +19,17 @@ var (
1819
)
1920

2021
var (
21-
cfg *config.Config
22-
cntr *counter.Manager
23-
gen *generator.Generator
22+
cfg *config.Config
23+
cntr *counter.Manager
24+
gen *generator.Generator
2425

2526
// Flags
26-
flagExt bool
27-
flagCopy bool
28-
flagQuiet bool
29-
flagCheck bool
30-
flagReset bool
31-
flagSet int
27+
flagExt bool
28+
flagCopy bool
29+
flagQuiet bool
30+
flagCheck bool
31+
flagReset bool
32+
flagSet int
3233
flagCounter bool
3334
)
3435

@@ -281,6 +282,23 @@ func main() {
281282
os.Exit(1)
282283
}
283284

285+
if wd, err := os.Getwd(); err == nil {
286+
if detectResult, detectErr := obsidian.Detect(wd); detectErr != nil {
287+
fmt.Fprintf(os.Stderr, "Obsidian detection warning: %v\n", detectErr)
288+
if detectResult != nil && detectResult.InVault {
289+
gen.ApplyLayouts(generator.LayoutOverrides{
290+
Default: detectResult.Layouts.Default,
291+
Daily: detectResult.Layouts.Daily,
292+
})
293+
}
294+
} else if detectResult.InVault {
295+
gen.ApplyLayouts(generator.LayoutOverrides{
296+
Default: detectResult.Layouts.Default,
297+
Daily: detectResult.Layouts.Daily,
298+
})
299+
}
300+
}
301+
284302
// Apply default extension flag from config
285303
if cfg.AlwaysExtension && !rootCmd.PersistentFlags().Changed("ext") {
286304
flagExt = true
@@ -289,4 +307,4 @@ func main() {
289307
if err := rootCmd.Execute(); err != nil {
290308
os.Exit(1)
291309
}
292-
}
310+
}

internal/generator/generator.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import (
77

88
// Generator handles timestamp generation with timezone support
99
type Generator struct {
10-
location *time.Location
10+
location *time.Location
11+
defaultLayout string
12+
dailyLayout string
1113
}
1214

1315
// New creates a new generator with the specified timezone
@@ -23,7 +25,9 @@ func New(timezone string) (*Generator, error) {
2325
}
2426

2527
return &Generator{
26-
location: loc,
28+
location: loc,
29+
defaultLayout: "2006-01-02-1504",
30+
dailyLayout: "2006-01-02",
2731
}, nil
2832
}
2933

@@ -34,17 +38,12 @@ func (g *Generator) now() time.Time {
3438

3539
// Default generates YYYY-MM-DD-HHMM format
3640
func (g *Generator) Default() string {
37-
now := g.now()
38-
return fmt.Sprintf("%04d-%02d-%02d-%02d%02d",
39-
now.Year(), now.Month(), now.Day(),
40-
now.Hour(), now.Minute())
41+
return g.now().Format(g.defaultLayout)
4142
}
4243

4344
// Daily generates YYYY-MM-DD format
4445
func (g *Generator) Daily() string {
45-
now := g.now()
46-
return fmt.Sprintf("%04d-%02d-%02d",
47-
now.Year(), now.Month(), now.Day())
46+
return g.now().Format(g.dailyLayout)
4847
}
4948

5049
// Fleeting generates YYYY-MM-DD-FHHMMSS format
@@ -93,4 +92,20 @@ func (g *Generator) FormatProject(num int, title string) string {
9392
result += " " + title
9493
}
9594
return result
96-
}
95+
}
96+
97+
// LayoutOverrides adjust dynamic layouts applied to generator output.
98+
type LayoutOverrides struct {
99+
Default string
100+
Daily string
101+
}
102+
103+
// ApplyLayouts updates the generator with new layouts when provided.
104+
func (g *Generator) ApplyLayouts(overrides LayoutOverrides) {
105+
if overrides.Default != "" {
106+
g.defaultLayout = overrides.Default
107+
}
108+
if overrides.Daily != "" {
109+
g.dailyLayout = overrides.Daily
110+
}
111+
}

internal/generator/generator_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,26 @@ func TestGenerator_FormatProject(t *testing.T) {
197197
}
198198
}
199199

200+
func TestGenerator_ApplyLayouts(t *testing.T) {
201+
gen, err := New("")
202+
if err != nil {
203+
t.Fatalf("Failed to create generator: %v", err)
204+
}
205+
206+
gen.ApplyLayouts(LayoutOverrides{
207+
Default: "20060102-1504",
208+
Daily: "20060102",
209+
})
210+
211+
if defaultStamp := gen.Default(); !regexp.MustCompile(`^\d{8}-\d{4}$`).MatchString(defaultStamp) {
212+
t.Fatalf("unexpected default layout result: %q", defaultStamp)
213+
}
214+
215+
if daily := gen.Daily(); !regexp.MustCompile(`^\d{8}$`).MatchString(daily) {
216+
t.Fatalf("unexpected daily layout result: %q", daily)
217+
}
218+
}
219+
200220
func TestGenerator_TimezoneConsistency(t *testing.T) {
201221
// Test that timezone is consistently applied
202222
gen, err := New("UTC")
@@ -212,4 +232,4 @@ func TestGenerator_TimezoneConsistency(t *testing.T) {
212232
if !strings.HasPrefix(daily, expectedPrefix[:10]) {
213233
t.Errorf("Daily() with UTC timezone = %v, should start with today's date in UTC", daily)
214234
}
215-
}
235+
}

0 commit comments

Comments
 (0)