buffer: Resolve symlinks in file paths

Otherwise we can't identify if we have the same file open multiple times via
different symlinks.
The test must be adapted to resolve symlinks in `findBuffer()`.
This commit is contained in:
Jöran Karl
2026-04-28 19:20:51 +02:00
parent e323cde09c
commit 2cb49c4653
4 changed files with 42 additions and 9 deletions
+3 -1
View File
@@ -11,6 +11,7 @@ import (
"github.com/micro-editor/micro/v2/internal/buffer"
"github.com/micro-editor/micro/v2/internal/config"
"github.com/micro-editor/micro/v2/internal/screen"
"github.com/micro-editor/micro/v2/internal/util"
"github.com/micro-editor/tcell/v2"
"github.com/stretchr/testify/assert"
)
@@ -157,8 +158,9 @@ func openFile(file string) {
func findBuffer(file string) *buffer.Buffer {
var buf *buffer.Buffer
file = util.ResolvePath(file)
for _, b := range buffer.OpenBuffers {
if b.Path == file {
if b.AbsPath == file {
buf = b
}
}
+5 -4
View File
@@ -355,9 +355,9 @@ func NewBufferFromString(text, path string, btype BufType) *Buffer {
// Places the cursor at startcursor. If startcursor is -1, -1 places the
// cursor at an autodetected location (based on savecursor or :LINE:COL)
func NewBuffer(r io.Reader, size int64, path string, btype BufType, cmd Command) *Buffer {
absPath, err := filepath.Abs(path)
if err != nil {
absPath = path
absPath := path
if btype == BTDefault && path != "" {
absPath = util.ResolvePath(path)
}
b := new(Buffer)
@@ -391,6 +391,7 @@ func NewBuffer(r io.Reader, size int64, path string, btype BufType, cmd Command)
}
config.UpdatePathGlobLocals(b.Settings, absPath)
var err error
b.encoding, err = htmlindex.Get(b.Settings["encoding"].(string))
if err != nil {
b.encoding = unicode.UTF8
@@ -489,7 +490,7 @@ func NewBuffer(r io.Reader, size int64, path string, btype BufType, cmd Command)
}
}
err = config.RunPluginFn("onBufferOpen", luar.New(ulua.L, b))
err := config.RunPluginFn("onBufferOpen", luar.New(ulua.L, b))
if err != nil {
screen.TermMessage(err)
}
+1 -4
View File
@@ -285,10 +285,7 @@ func (b *Buffer) saveToFile(filename string, withSudo bool, autoSave bool) error
return errors.New("Error: " + filename + " is not a regular file and cannot be saved")
}
absFilename, err := filepath.Abs(filename)
if err != nil {
return err
}
absFilename := util.ResolvePath(filename)
// Get the leading path to the file | "." is returned if there's no leading path provided
if dirname := filepath.Dir(absFilename); dirname != "." {
+33
View File
@@ -489,6 +489,39 @@ func DetermineEscapePath(dir string, path string) (string, string) {
return url, ""
}
// ResolvePath provides the absolute file path for the given relative file path
// as well as resolves symlinks. If it fails to get the absolute path or to
// resolve symlinks, it returns unresolved path in place of resolved one.
func ResolvePath(path string) string {
absPath, err := filepath.Abs(path)
if err != nil {
absPath = path
}
var remainder []string
for {
resolvedPath, err := filepath.EvalSymlinks(absPath)
if err == nil {
absPath = resolvedPath
break
}
if !errors.Is(err, fs.ErrNotExist) {
break
}
remainder = append([]string{filepath.Base(absPath)}, remainder...)
absPath = filepath.Dir(absPath)
}
if len(remainder) > 0 {
remainder = append([]string{absPath}, remainder...)
absPath = filepath.Join(remainder...)
absPath = filepath.Clean(absPath)
}
return absPath
}
// GetLeadingWhitespace returns the leading whitespace of the given byte array
func GetLeadingWhitespace(b []byte) []byte {
ws := []byte{}