| 1642 | } |
| 1643 | |
| 1644 | func (v *Vault) DuplicateNote(rel string) (NoteMeta, error) { |
| 1645 | v.mu.Lock() |
| 1646 | defer v.mu.Unlock() |
| 1647 | abs, err := SafeJoin(v.root, rel) |
| 1648 | if err != nil { |
| 1649 | return NoteMeta{}, err |
| 1650 | } |
| 1651 | folder, _ := v.folderOf(abs) |
| 1652 | title := strings.TrimSuffix(filepath.Base(abs), filepath.Ext(abs)) + " copy" |
| 1653 | newAbs := uniquePath(filepath.Dir(abs), sanitizeFileStem(title), noteExt(abs)) |
| 1654 | if err := copyFile(abs, newAbs, v.fileMode); err != nil { |
| 1655 | return NoteMeta{}, err |
| 1656 | } |
| 1657 | v.invalidateTextSearchCache() |
| 1658 | meta, err := v.readMeta(folder, newAbs) |
| 1659 | if err != nil { |
| 1660 | return NoteMeta{}, err |
| 1661 | } |
| 1662 | if err := v.copyNoteCommentsLocked(rel, meta.Path); err != nil { |
| 1663 | return NoteMeta{}, err |
| 1664 | } |
| 1665 | return meta, nil |
| 1666 | } |
| 1667 | |
| 1668 | func (v *Vault) MoveNote(rel string, target NoteFolder, targetSubpath string) (NoteMeta, error) { |
| 1669 | v.mu.Lock() |