Add editor packages
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
package editor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"code.chimeric.al/dwrz/wen/internal/editor/buffer"
|
||||
"code.chimeric.al/dwrz/wen/internal/editor/event"
|
||||
)
|
||||
|
||||
// load files into editor buffers.
|
||||
func (e *Editor) load(files []string) {
|
||||
// Attempt to deduplicate any files.
|
||||
var (
|
||||
unique = map[string]struct{}{}
|
||||
paths []string
|
||||
)
|
||||
for _, f := range files {
|
||||
path, err := filepath.Abs(f)
|
||||
if err != nil {
|
||||
e.log.Error(
|
||||
"failed to get absolute path",
|
||||
slog.String("file", f),
|
||||
slog.Any("error", err),
|
||||
)
|
||||
|
||||
path = filepath.Clean(f)
|
||||
}
|
||||
|
||||
if _, exists := unique[path]; !exists {
|
||||
unique[path] = struct{}{}
|
||||
paths = append(paths, path)
|
||||
}
|
||||
}
|
||||
|
||||
// Load the files.
|
||||
// Set the first successfully loaded file as the active buffer.
|
||||
var setActive bool
|
||||
for _, name := range paths {
|
||||
p := buffer.NewBufferParams{
|
||||
Name: name,
|
||||
Log: e.log,
|
||||
}
|
||||
|
||||
b, err := buffer.Open(p)
|
||||
// Create the file if it doesn't exist.
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
b, err = buffer.Create(p)
|
||||
}
|
||||
// If there was an error, report it to the user.
|
||||
if err != nil {
|
||||
e.prompt.SetText(fmt.Sprintf(
|
||||
"failed to load buffer %s: %v",
|
||||
name, err,
|
||||
))
|
||||
continue
|
||||
}
|
||||
|
||||
e.log.Debug("loaded buffer", slog.String("name", name))
|
||||
|
||||
e.setBuffer(b)
|
||||
|
||||
if !setActive {
|
||||
e.setActiveBuffer(name)
|
||||
setActive = true
|
||||
}
|
||||
}
|
||||
|
||||
if e.prompt.Text() == "" {
|
||||
e.prompt.SetText("loaded buffers")
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Editor) renameBuffer(b *buffer.Buffer, name string) error {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
oldName := b.Name()
|
||||
if err := b.SaveAs(name); err != nil {
|
||||
return fmt.Errorf("failed to save as %s: %v", name, err)
|
||||
}
|
||||
|
||||
delete(e.buffers, oldName)
|
||||
e.buffers[name] = b
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// setActiveBuffer sets the named buffer as the active buffer.
|
||||
func (e *Editor) setActiveBuffer(name string) {
|
||||
e.mu.Lock()
|
||||
b, exists := e.buffers[name]
|
||||
if !exists {
|
||||
e.mu.Unlock()
|
||||
e.events <- event.NewError(fmt.Errorf(
|
||||
"failed to set active buffer: %s does not exist", name,
|
||||
))
|
||||
return
|
||||
}
|
||||
|
||||
e.active = b
|
||||
e.mu.Unlock()
|
||||
|
||||
e.log.Debug("set active buffer", slog.String("name", b.Name()))
|
||||
}
|
||||
|
||||
// setBuffer stores a buffer in the editor's buffer map.
|
||||
func (e *Editor) setBuffer(b *buffer.Buffer) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
e.buffers[b.Name()] = b
|
||||
}
|
||||
Reference in New Issue
Block a user