mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-06 00:38:49 +01:00
🎨 Search replace generate file history https://github.com/siyuan-note/siyuan/issues/7864
This commit is contained in:
parent
fb6248c3e5
commit
5df0d4c0ce
3 changed files with 75 additions and 13 deletions
|
|
@ -266,6 +266,7 @@ export const openHistory = () => {
|
|||
<option value="delete">delete</option>
|
||||
<option value="format">format</option>
|
||||
<option value="sync">sync</option>
|
||||
<option value="replace">replace</option>
|
||||
</select>
|
||||
<span class="fn__space"></span>
|
||||
<select data-type="notebookselect" class="b3-select" style="min-width: auto">
|
||||
|
|
|
|||
|
|
@ -547,15 +547,20 @@ func (box *Box) recentModifiedDocs() (ret []string) {
|
|||
}
|
||||
|
||||
const (
|
||||
HistoryOpClean = "clean"
|
||||
HistoryOpUpdate = "update"
|
||||
HistoryOpDelete = "delete"
|
||||
HistoryOpFormat = "format"
|
||||
HistoryOpSync = "sync"
|
||||
HistoryOpClean = "clean"
|
||||
HistoryOpUpdate = "update"
|
||||
HistoryOpDelete = "delete"
|
||||
HistoryOpFormat = "format"
|
||||
HistoryOpSync = "sync"
|
||||
HistoryOpReplace = "replace"
|
||||
)
|
||||
|
||||
func GetHistoryDir(suffix string) (ret string, err error) {
|
||||
ret = filepath.Join(util.HistoryDir, time.Now().Format("2006-01-02-150405")+"-"+suffix)
|
||||
return getHistoryDir(suffix, time.Now())
|
||||
}
|
||||
|
||||
func getHistoryDir(suffix string, t time.Time) (ret string, err error) {
|
||||
ret = filepath.Join(util.HistoryDir, t.Format("2006-01-02-150405")+"-"+suffix)
|
||||
if err = os.MkdirAll(ret, 0755); nil != err {
|
||||
logging.LogErrorf("make history dir failed: %s", err)
|
||||
return
|
||||
|
|
@ -584,7 +589,7 @@ func ReindexHistory() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
var validOps = []string{HistoryOpClean, HistoryOpUpdate, HistoryOpDelete, HistoryOpFormat, HistoryOpSync}
|
||||
var validOps = []string{HistoryOpClean, HistoryOpUpdate, HistoryOpDelete, HistoryOpFormat, HistoryOpSync, HistoryOpReplace}
|
||||
|
||||
const (
|
||||
HistoryTypeDocName = 0
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/siyuan-note/siyuan/kernel/task"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
|
@ -35,10 +36,12 @@ import (
|
|||
"github.com/88250/lute/lex"
|
||||
"github.com/88250/lute/parse"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/siyuan-note/filelock"
|
||||
"github.com/siyuan-note/logging"
|
||||
"github.com/siyuan-note/siyuan/kernel/conf"
|
||||
"github.com/siyuan-note/siyuan/kernel/search"
|
||||
"github.com/siyuan-note/siyuan/kernel/sql"
|
||||
"github.com/siyuan-note/siyuan/kernel/task"
|
||||
"github.com/siyuan-note/siyuan/kernel/treenode"
|
||||
"github.com/siyuan-note/siyuan/kernel/util"
|
||||
"github.com/xrash/smetrics"
|
||||
|
|
@ -215,16 +218,42 @@ func FindReplace(keyword, replacement string, ids []string, method int) (err err
|
|||
ids = gulu.Str.RemoveDuplicatedElem(ids)
|
||||
var renameRoots []*ast.Node
|
||||
renameRootTitles := map[string]string{}
|
||||
cachedTrees := map[string]*parse.Tree{}
|
||||
now := time.Now()
|
||||
for _, id := range ids {
|
||||
var tree *parse.Tree
|
||||
tree, err = loadTreeByBlockID(id)
|
||||
if nil != err {
|
||||
return
|
||||
bt := treenode.GetBlockTree(id)
|
||||
if nil == bt {
|
||||
continue
|
||||
}
|
||||
|
||||
tree := cachedTrees[bt.RootID]
|
||||
if nil != tree {
|
||||
continue
|
||||
}
|
||||
|
||||
tree, _ = loadTreeByBlockID(id)
|
||||
if nil == tree {
|
||||
continue
|
||||
}
|
||||
|
||||
generateReplaceHistory(tree, now)
|
||||
cachedTrees[bt.RootID] = tree
|
||||
}
|
||||
|
||||
for _, id := range ids {
|
||||
bt := treenode.GetBlockTree(id)
|
||||
if nil == bt {
|
||||
continue
|
||||
}
|
||||
|
||||
tree := cachedTrees[bt.RootID]
|
||||
if nil == tree {
|
||||
continue
|
||||
}
|
||||
|
||||
node := treenode.GetNodeInTree(tree, id)
|
||||
if nil == node {
|
||||
return
|
||||
continue
|
||||
}
|
||||
|
||||
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
|
|
@ -338,6 +367,33 @@ func FindReplace(keyword, replacement string, ids []string, method int) (err err
|
|||
return
|
||||
}
|
||||
|
||||
func generateReplaceHistory(tree *parse.Tree, t time.Time) {
|
||||
historyDir, err := getHistoryDir(HistoryOpReplace, t)
|
||||
if nil != err {
|
||||
logging.LogErrorf("get history dir failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
historyPath := filepath.Join(historyDir, tree.Box, tree.Path)
|
||||
if err = os.MkdirAll(filepath.Dir(historyPath), 0755); nil != err {
|
||||
logging.LogErrorf("generate history failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
var data []byte
|
||||
if data, err = filelock.ReadFile(filepath.Join(util.DataDir, tree.Box, tree.Path)); err != nil {
|
||||
logging.LogErrorf("generate history failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = gulu.File.WriteFileSafer(historyPath, data, 0644); err != nil {
|
||||
logging.LogErrorf("generate history failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
indexHistoryDir(filepath.Base(historyDir), util.NewLute())
|
||||
}
|
||||
|
||||
// FullTextSearchBlock 搜索内容块。
|
||||
//
|
||||
// method:0:关键字,1:查询语法,2:SQL,3:正则表达式
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue