2021-12-11 17:25:40 +00:00
|
|
|
package lsp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
"github.com/mickael-menu/zk/internal/core"
|
|
|
|
dateutil "github.com/mickael-menu/zk/internal/util/date"
|
|
|
|
"github.com/mickael-menu/zk/internal/util/errors"
|
|
|
|
"github.com/mickael-menu/zk/internal/util/opt"
|
|
|
|
"github.com/tliron/glsp"
|
|
|
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
|
|
|
)
|
|
|
|
|
|
|
|
const cmdNew = "zk.new"
|
|
|
|
|
|
|
|
type cmdNewOpts struct {
|
2022-12-19 13:28:15 +00:00
|
|
|
Title string `json:"title"`
|
|
|
|
Content string `json:"content"`
|
|
|
|
Dir string `json:"dir"`
|
|
|
|
Group string `json:"group"`
|
|
|
|
Template string `json:"template"`
|
|
|
|
Extra map[string]string `json:"extra"`
|
|
|
|
Date string `json:"date"`
|
|
|
|
Edit jsonBoolean `json:"edit"`
|
|
|
|
DryRun jsonBoolean `json:"dryRun"`
|
|
|
|
InsertLinkAtLocation *protocol.Location `json:"insertLinkAtLocation"`
|
|
|
|
InsertContentAtLocation *protocol.Location `json:"insertContentAtLocation"`
|
2021-12-11 17:25:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func executeCommandNew(notebook *core.Notebook, documents *documentStore, context *glsp.Context, args []interface{}) (interface{}, error) {
|
|
|
|
var opts cmdNewOpts
|
|
|
|
if len(args) > 1 {
|
|
|
|
arg, ok := args[1].(map[string]interface{})
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("%s expects a dictionary of options as second argument, got: %v", cmdNew, args[1])
|
|
|
|
}
|
|
|
|
err := unmarshalJSON(arg, &opts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "failed to parse %s args, got: %v", cmdNew, arg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
date, err := dateutil.TimeFromNatural(opts.Date)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "%s, failed to parse the `date` option", opts.Date)
|
|
|
|
}
|
|
|
|
|
|
|
|
note, err := notebook.NewNote(core.NewNoteOpts{
|
|
|
|
Title: opt.NewNotEmptyString(opts.Title),
|
|
|
|
Content: opts.Content,
|
|
|
|
Directory: opt.NewNotEmptyString(opts.Dir),
|
|
|
|
Group: opt.NewNotEmptyString(opts.Group),
|
|
|
|
Template: opt.NewNotEmptyString(opts.Template),
|
|
|
|
Extra: opts.Extra,
|
2022-12-19 13:28:15 +00:00
|
|
|
DryRun: bool(opts.DryRun),
|
2021-12-11 17:25:40 +00:00
|
|
|
Date: date,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
var noteExists core.ErrNoteExists
|
|
|
|
if !errors.As(err, ¬eExists) {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
note, err = notebook.FindNote(core.NoteFindOpts{
|
|
|
|
IncludeHrefs: []string{noteExists.Name},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if note == nil {
|
|
|
|
return nil, errors.New("zk.new could not generate a new note")
|
|
|
|
}
|
|
|
|
|
2022-12-19 13:28:15 +00:00
|
|
|
if opts.InsertContentAtLocation != nil {
|
|
|
|
go context.Call(protocol.ServerWorkspaceApplyEdit, protocol.ApplyWorkspaceEditParams{
|
|
|
|
Edit: protocol.WorkspaceEdit{
|
|
|
|
Changes: map[string][]protocol.TextEdit{
|
|
|
|
opts.InsertContentAtLocation.URI: {{Range: opts.InsertContentAtLocation.Range, NewText: note.RawContent}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !opts.DryRun && opts.InsertLinkAtLocation != nil {
|
2021-12-11 17:25:40 +00:00
|
|
|
doc, ok := documents.Get(opts.InsertLinkAtLocation.URI)
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("can't insert link in %s", opts.InsertLinkAtLocation.URI)
|
|
|
|
}
|
|
|
|
linkFormatter, err := notebook.NewLinkFormatter()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-01-10 13:28:14 +00:00
|
|
|
path := core.NotebookPath{
|
|
|
|
Path: note.Path,
|
|
|
|
BasePath: notebook.Path,
|
|
|
|
WorkingDir: filepath.Dir(doc.Path),
|
|
|
|
}
|
|
|
|
linkFormatterContext, err := core.NewLinkFormatterContext(path, note.Title, note.Metadata)
|
2021-12-11 17:25:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
link, err := linkFormatter(linkFormatterContext)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
go context.Call(protocol.ServerWorkspaceApplyEdit, protocol.ApplyWorkspaceEditParams{
|
|
|
|
Edit: protocol.WorkspaceEdit{
|
|
|
|
Changes: map[string][]protocol.TextEdit{
|
|
|
|
opts.InsertLinkAtLocation.URI: {{Range: opts.InsertLinkAtLocation.Range, NewText: link}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
absPath := filepath.Join(notebook.Path, note.Path)
|
2022-12-19 13:28:15 +00:00
|
|
|
if !opts.DryRun && opts.Edit {
|
2021-12-11 17:25:40 +00:00
|
|
|
go context.Call(protocol.ServerWindowShowDocument, protocol.ShowDocumentParams{
|
|
|
|
URI: pathToURI(absPath),
|
|
|
|
TakeFocus: boolPtr(true),
|
|
|
|
}, nil)
|
|
|
|
}
|
|
|
|
|
2022-12-19 13:28:15 +00:00
|
|
|
return map[string]interface{}{
|
|
|
|
"path": absPath,
|
|
|
|
"content": note.RawContent,
|
|
|
|
}, nil
|
2021-12-11 17:25:40 +00:00
|
|
|
}
|