ModTime time.Time
}
-// NewBufferFromFile opens a new buffer using the given filepath
+// NewBufferFromFile opens a new buffer using the given path
// It will also automatically handle `~`, and line/column with filename:l:c
-// It will return an empty buffer if the filepath does not exist
+// It will return an empty buffer if the path does not exist
// and an error if the file is a directory
func NewBufferFromFile(path string) (*Buffer, error) {
- filename := GetPath(path)
+ filename, cursorPosition := GetPathAndCursorPosition(path)
filename = ReplaceHome(filename)
file, err := os.Open(filename)
fileInfo, _ := os.Stat(filename)
var buf *Buffer
if err != nil {
// File does not exist -- create an empty buffer with that name
- buf = NewBufferFromString("", path)
+ buf = NewBufferFromString("", filename)
} else {
- buf = NewBuffer(file, FSize(file), path)
+ buf = NewBuffer(file, FSize(file), filename, cursorPosition)
}
return buf, nil
}
-// NewBufferFromString creates a new buffer containing the given
-// string
+// NewBufferFromString creates a new buffer containing the given string
func NewBufferFromString(text, path string) *Buffer {
- return NewBuffer(strings.NewReader(text), int64(len(text)), path)
+ return NewBuffer(strings.NewReader(text), int64(len(text)), path, []string{"0", "0"})
}
// NewBuffer creates a new buffer from a given reader with a given path
-func NewBuffer(reader io.Reader, size int64, path string) *Buffer {
- startpos := Loc{0, 0}
- startposErr := true
- if strings.Contains(path, ":") {
- var err error
- split := strings.Split(path, ":")
- path = split[0]
- startpos.Y, err = strconv.Atoi(split[1])
- if err != nil {
- messenger.Error("Error opening file: ", err)
- } else {
- startposErr = false
- if len(split) > 2 {
- startpos.X, err = strconv.Atoi(split[2])
- if err != nil {
- messenger.Error("Error opening file: ", err)
- }
- }
- }
- }
+func NewBuffer(reader io.Reader, size int64, path string, cursorPosition []string) *Buffer {
+ cursorLocation, cursorLocationError := ParseCursorLocation(cursorPosition)
if path != "" {
for _, tab := range tabs {
// Put the cursor at the first spot
cursorStartX := 0
cursorStartY := 0
- // If -startpos LINE,COL was passed, use start position LINE,COL
- if len(*flagStartPos) > 0 || !startposErr {
+ // If -cursorLocation LINE,COL was passed, use start position LINE,COL
+ if len(*flagStartPos) > 0 || cursorLocationError == nil {
positions := strings.Split(*flagStartPos, ",")
- if len(positions) == 2 || !startposErr {
+ if len(positions) == 2 || cursorLocationError == nil {
var lineNum, colNum int
var errPos1, errPos2 error
- if !startposErr {
- lineNum = startpos.Y
- colNum = startpos.X
+ if cursorLocationError == nil {
+ lineNum = cursorLocation.Y
+ colNum = cursorLocation.X
} else {
lineNum, errPos1 = strconv.Atoi(positions[0])
colNum, errPos2 = strconv.Atoi(positions[1])
InitLocalSettings(b)
- if startposErr && len(*flagStartPos) == 0 && (b.Settings["savecursor"].(bool) || b.Settings["saveundo"].(bool)) {
+ if cursorLocationError != nil && len(*flagStartPos) == 0 && (b.Settings["savecursor"].(bool) || b.Settings["saveundo"].(bool)) {
// If either savecursor or saveundo is turned on, we need to load the serialized information
// from ~/.config/micro/buffers
file, err := os.Open(configDir + "/buffers/" + EscapePath(b.AbsPath))
t.Error("WidthOfLargeRunes 5 Failed. Got", w)
}
}
+
+func assertEqual(t *testing.T, expected interface{}, result interface{}) {
+ if expected != result {
+ t.Fatalf("Expected: %d != Got: %d", expected, result)
+ }
+}
+
+func assertTrue(t *testing.T, condition bool) {
+ if !condition {
+ t.Fatalf("Condition was not true. Got false")
+ }
+}
+
+func TestGetPathRelativeWithDot(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("./myfile:10:5")
+
+ assertEqual(t, path, "./myfile")
+ assertEqual(t, "10", cursorPosition[0])
+ assertEqual(t, "5", cursorPosition[1])
+}
+func TestGetPathRelativeWithDotWindows(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition(".\\myfile:10:5")
+
+ assertEqual(t, path, ".\\myfile")
+ assertEqual(t, "10", cursorPosition[0])
+ assertEqual(t, cursorPosition[1], "5")
+}
+func TestGetPathRelativeNoDot(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("myfile:10:5")
+
+ assertEqual(t, path, "myfile")
+ assertEqual(t, "10", cursorPosition[0])
+
+ assertEqual(t, cursorPosition[1], "5")
+}
+func TestGetPathAbsoluteWindows(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("C:\\myfile:10:5")
+
+ assertEqual(t, path, "C:\\myfile")
+ assertEqual(t, "10", cursorPosition[0])
+
+ assertEqual(t, cursorPosition[1], "5")
+
+ path, cursorPosition = GetPathAndCursorPosition("C:/myfile:10:5")
+
+ assertEqual(t, path, "C:/myfile")
+ assertEqual(t, "10", cursorPosition[0])
+
+ assertEqual(t, cursorPosition[1], "5")
+}
+func TestGetPathAbsoluteUnix(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("/home/user/myfile:10:5")
+
+ assertEqual(t, path, "/home/user/myfile")
+ assertEqual(t, "10", cursorPosition[0])
+
+ assertEqual(t, cursorPosition[1], "5")
+}
+
+func TestGetPathRelativeWithDotWithoutLineAndColumn(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("./myfile")
+
+ assertEqual(t, path, "./myfile")
+ assertEqual(t, "0", cursorPosition[0])
+
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathRelativeWithDotWindowsWithoutLineAndColumn(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition(".\\myfile")
+
+ assertEqual(t, path, ".\\myfile")
+ assertEqual(t, "0", cursorPosition[0])
+
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathRelativeNoDotWithoutLineAndColumn(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("myfile")
+
+ assertEqual(t, path, "myfile")
+ assertEqual(t, "0", cursorPosition[0])
+
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathAbsoluteWindowsWithoutLineAndColumn(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("C:\\myfile")
+
+ assertEqual(t, path, "C:\\myfile")
+ assertEqual(t, "0", cursorPosition[0])
+
+ assertEqual(t, "0", cursorPosition[1])
+
+ path, cursorPosition = GetPathAndCursorPosition("C:/myfile")
+
+ assertEqual(t, path, "C:/myfile")
+ assertEqual(t, "0", cursorPosition[0])
+
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathAbsoluteUnixWithoutLineAndColumn(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("/home/user/myfile")
+
+ assertEqual(t, path, "/home/user/myfile")
+ assertEqual(t, "0", cursorPosition[0])
+
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathSingleLetterFileRelativePath(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("a:5:6")
+
+ assertEqual(t, path, "a")
+ assertEqual(t, "5", cursorPosition[0])
+ assertEqual(t, "6", cursorPosition[1])
+}
+func TestGetPathSingleLetterFileAbsolutePathWindows(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("C:\\a:5:6")
+
+ assertEqual(t, path, "C:\\a")
+ assertEqual(t, "5", cursorPosition[0])
+ assertEqual(t, "6", cursorPosition[1])
+
+ path, cursorPosition = GetPathAndCursorPosition("C:/a:5:6")
+
+ assertEqual(t, path, "C:/a")
+ assertEqual(t, "5", cursorPosition[0])
+ assertEqual(t, "6", cursorPosition[1])
+}
+func TestGetPathSingleLetterFileAbsolutePathUnix(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("/home/user/a:5:6")
+
+ assertEqual(t, path, "/home/user/a")
+ assertEqual(t, "5", cursorPosition[0])
+ assertEqual(t, "6", cursorPosition[1])
+}
+func TestGetPathSingleLetterFileAbsolutePathWindowsWithoutLineAndColumn(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("C:\\a")
+
+ assertEqual(t, path, "C:\\a")
+ assertEqual(t, "0", cursorPosition[0])
+
+ assertEqual(t, "0", cursorPosition[1])
+
+ path, cursorPosition = GetPathAndCursorPosition("C:/a")
+
+ assertEqual(t, path, "C:/a")
+ assertEqual(t, "0", cursorPosition[0])
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathSingleLetterFileAbsolutePathUnixWithoutLineAndColumn(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("/home/user/a")
+
+ assertEqual(t, path, "/home/user/a")
+ assertEqual(t, "0", cursorPosition[0])
+ assertEqual(t, "0", cursorPosition[1])
+}
+
+// TODO test for only line without a column
+func TestGetPathRelativeWithDotOnlyLine(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("./myfile:10")
+
+ assertEqual(t, path, "./myfile")
+ assertEqual(t, "10", cursorPosition[0])
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathRelativeWithDotWindowsOnlyLine(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition(".\\myfile:10")
+
+ assertEqual(t, path, ".\\myfile")
+ assertEqual(t, "10", cursorPosition[0])
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathRelativeNoDotOnlyLine(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("myfile:10")
+
+ assertEqual(t, path, "myfile")
+ assertEqual(t, "10", cursorPosition[0])
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathAbsoluteWindowsOnlyLine(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("C:\\myfile:10")
+
+ assertEqual(t, path, "C:\\myfile")
+ assertEqual(t, "10", cursorPosition[0])
+ assertEqual(t, "0", cursorPosition[1])
+
+ path, cursorPosition = GetPathAndCursorPosition("C:/myfile:10")
+
+ assertEqual(t, path, "C:/myfile")
+ assertEqual(t, "10", cursorPosition[0])
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestGetPathAbsoluteUnixOnlyLine(t *testing.T) {
+ path, cursorPosition := GetPathAndCursorPosition("/home/user/myfile:10")
+
+ assertEqual(t, path, "/home/user/myfile")
+ assertEqual(t, "10", cursorPosition[0])
+ assertEqual(t, "0", cursorPosition[1])
+}
+func TestParseCursorLocationOneArg(t *testing.T) {
+ location, err := ParseCursorLocation([]string{"3"})
+
+ assertEqual(t, 3, location.Y)
+ assertEqual(t, 0, location.X)
+ assertEqual(t, nil, err)
+}
+func TestParseCursorLocationTwoArgs(t *testing.T) {
+ location, err := ParseCursorLocation([]string{"3", "15"})
+
+ assertEqual(t, 3, location.Y)
+ assertEqual(t, 15, location.X)
+ assertEqual(t, nil, err)
+}
+func TestParseCursorLocationNoArgs(t *testing.T) {
+ location, err := ParseCursorLocation([]string{})
+ // the expected result is the start position - 0, 0
+ assertEqual(t, 0, location.Y)
+ assertEqual(t, 0, location.X)
+ assertEqual(t, nil, err)
+}
+func TestParseCursorLocationFirstArgNotValidNumber(t *testing.T) {
+ // the messenger is necessary as ParseCursorLocation
+ // puts a message in it on error
+ messenger = new(Messenger)
+ _, err := ParseCursorLocation([]string{"apples", "1"})
+ // the expected result is the start position - 0, 0
+ assertTrue(t, messenger.hasMessage)
+ assertTrue(t, err != nil)
+}
+func TestParseCursorLocationSecondArgNotValidNumber(t *testing.T) {
+ // the messenger is necessary as ParseCursorLocation
+ // puts a message in it on error
+ messenger = new(Messenger)
+ _, err := ParseCursorLocation([]string{"1", "apples"})
+ // the expected result is the start position - 0, 0
+ assertTrue(t, messenger.hasMessage)
+ assertTrue(t, err != nil)
+}