Skip to content

Commit 253065a

Browse files
authored
Merge pull request #3997 from JoeKar/fix/symlinks
buffer: Store potential resolved symlinks as `AbsPath`
2 parents bd0003b + 2cb49c4 commit 253065a

4 files changed

Lines changed: 47 additions & 12 deletions

File tree

cmd/micro/micro_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/micro-editor/micro/v2/internal/buffer"
1212
"github.com/micro-editor/micro/v2/internal/config"
1313
"github.com/micro-editor/micro/v2/internal/screen"
14+
"github.com/micro-editor/micro/v2/internal/util"
1415
"github.com/micro-editor/tcell/v2"
1516
"github.com/stretchr/testify/assert"
1617
)
@@ -157,8 +158,9 @@ func openFile(file string) {
157158

158159
func findBuffer(file string) *buffer.Buffer {
159160
var buf *buffer.Buffer
161+
file = util.ResolvePath(file)
160162
for _, b := range buffer.OpenBuffers {
161-
if b.Path == file {
163+
if b.AbsPath == file {
162164
buf = b
163165
}
164166
}

internal/buffer/buffer.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,9 @@ func NewBufferFromString(text, path string, btype BufType) *Buffer {
355355
// Places the cursor at startcursor. If startcursor is -1, -1 places the
356356
// cursor at an autodetected location (based on savecursor or :LINE:COL)
357357
func NewBuffer(r io.Reader, size int64, path string, btype BufType, cmd Command) *Buffer {
358-
absPath, err := filepath.Abs(path)
359-
if err != nil {
360-
absPath = path
358+
absPath := path
359+
if btype == BTDefault && path != "" {
360+
absPath = util.ResolvePath(path)
361361
}
362362

363363
b := new(Buffer)
@@ -391,6 +391,7 @@ func NewBuffer(r io.Reader, size int64, path string, btype BufType, cmd Command)
391391
}
392392
config.UpdatePathGlobLocals(b.Settings, absPath)
393393

394+
var err error
394395
b.encoding, err = htmlindex.Get(b.Settings["encoding"].(string))
395396
if err != nil {
396397
b.encoding = unicode.UTF8
@@ -489,7 +490,7 @@ func NewBuffer(r io.Reader, size int64, path string, btype BufType, cmd Command)
489490
}
490491
}
491492

492-
err = config.RunPluginFn("onBufferOpen", luar.New(ulua.L, b))
493+
err := config.RunPluginFn("onBufferOpen", luar.New(ulua.L, b))
493494
if err != nil {
494495
screen.TermMessage(err)
495496
}
@@ -524,10 +525,12 @@ func (b *Buffer) Close() {
524525
// Fini should be called when a buffer is closed and performs
525526
// some cleanup
526527
func (b *Buffer) Fini() {
527-
if !b.Modified() {
528-
b.Serialize()
528+
if !b.Shared() {
529+
if !b.Modified() {
530+
b.Serialize()
531+
}
532+
b.CancelBackup()
529533
}
530-
b.CancelBackup()
531534

532535
if b.Type == BTStdout {
533536
fmt.Fprint(util.Stdout, string(b.Bytes()))

internal/buffer/save.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,7 @@ func (b *Buffer) saveToFile(filename string, withSudo bool, autoSave bool) error
283283
return errors.New("Error: " + filename + " is not a regular file and cannot be saved")
284284
}
285285

286-
absFilename, err := filepath.Abs(filename)
287-
if err != nil {
288-
return err
289-
}
286+
absFilename := util.ResolvePath(filename)
290287

291288
// Get the leading path to the file | "." is returned if there's no leading path provided
292289
if dirname := filepath.Dir(absFilename); dirname != "." {

internal/util/util.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,39 @@ func DetermineEscapePath(dir string, path string) (string, string) {
489489
return url, ""
490490
}
491491

492+
// ResolvePath provides the absolute file path for the given relative file path
493+
// as well as resolves symlinks. If it fails to get the absolute path or to
494+
// resolve symlinks, it returns unresolved path in place of resolved one.
495+
func ResolvePath(path string) string {
496+
absPath, err := filepath.Abs(path)
497+
if err != nil {
498+
absPath = path
499+
}
500+
501+
var remainder []string
502+
for {
503+
resolvedPath, err := filepath.EvalSymlinks(absPath)
504+
if err == nil {
505+
absPath = resolvedPath
506+
break
507+
}
508+
if !errors.Is(err, fs.ErrNotExist) {
509+
break
510+
}
511+
512+
remainder = append([]string{filepath.Base(absPath)}, remainder...)
513+
absPath = filepath.Dir(absPath)
514+
}
515+
516+
if len(remainder) > 0 {
517+
remainder = append([]string{absPath}, remainder...)
518+
absPath = filepath.Join(remainder...)
519+
absPath = filepath.Clean(absPath)
520+
}
521+
522+
return absPath
523+
}
524+
492525
// GetLeadingWhitespace returns the leading whitespace of the given byte array
493526
func GetLeadingWhitespace(b []byte) []byte {
494527
ws := []byte{}

0 commit comments

Comments
 (0)