package main import ( "fmt" "path/filepath" "strconv" "strings" "typer/runestring" "github.com/gdamore/tcell/v2" ) type TopMenuButton struct { Name string PosX int Action func(w *Window, b *TopMenuButton) } var TopMenuButtons = make([]TopMenuButton, 0) func initTopMenu() { // Buttons fileButton := TopMenuButton{ Name: "File", Action: func(window *Window, button *TopMenuButton) { ClearDropdowns() y := 0 if window.ShowTopMenu { y++ } d := CreateDropdownMenu([]string{"New", "Save", "Open", "Close", "Quit"}, button.PosX, y, 0, func(i int) { switch i { case 0: RunCommand(window, "new-buffer") case 1: RunCommand(window, "save") case 2: RunCommand(window, "open") case 3: RunCommand(window, "close-buffer") case 4: RunCommand(window, "quit") } ClearDropdowns() }) ActiveDropdown = d window.CursorMode = CursorModeDropdown }, } EditButton := TopMenuButton{ Name: "Edit", Action: func(window *Window, button *TopMenuButton) { ClearDropdowns() y := 0 if window.ShowTopMenu { y++ } d := CreateDropdownMenu([]string{"Cut", "Copy", "Paste"}, button.PosX, y, 0, func(i int) { switch i { case 0: RunCommand(window, "cut") case 1: RunCommand(window, "copy") case 2: RunCommand(window, "paste") } ClearDropdowns() window.CursorMode = CursorModeBuffer }) ActiveDropdown = d window.CursorMode = CursorModeDropdown }, } Buffers := TopMenuButton{ Name: "Buffers", Action: func(window *Window, button *TopMenuButton) { ClearDropdowns() y := 0 if window.ShowTopMenu { y++ } buffersSlice := make([]string, 0) selected := 0 for i, buffer := range Buffers { if window.CurrentBuffer == buffer { buffersSlice = append(buffersSlice, fmt.Sprintf("[%d] * %s", i+1, buffer.Name)) selected = i } else { buffersSlice = append(buffersSlice, fmt.Sprintf("[%d] %s", i+1, buffer.Name)) } } d := CreateDropdownMenu(buffersSlice, button.PosX, y, 0, func(i int) { window.CurrentBuffer = Buffers[i] window.PrintMessage(fmt.Sprintf("Set current buffer to '%s'", window.CurrentBuffer.Name), TYPER_MESSAGE_INFO) ClearDropdowns() window.CursorMode = CursorModeBuffer }) d.Selected = selected ActiveDropdown = d window.CursorMode = CursorModeDropdown }, } // Append buttons TopMenuButtons = append(TopMenuButtons, fileButton, EditButton, Buffers) } func drawTopMenu(window *Window) { screen := window.screen topMenuStyle := tcell.StyleDefault.Background(CurrentStyle.TopMenuBg).Foreground(CurrentStyle.TopMenuFg) sizeX, _ := screen.Size() for x := 0; x < sizeX; x++ { screen.SetContent(x, 0, ' ', nil, topMenuStyle) } currentX := 1 for i, button := range TopMenuButtons { drawText(screen, currentX, 0, currentX+len(button.Name), 0, topMenuStyle, button.Name) TopMenuButtons[i].PosX = currentX currentX += len(button.Name) + 1 } // Draw buffer info bufferInfoMsg := getBufferInfoMsg(window) if sizeX-len(bufferInfoMsg)-1 > currentX+2 { drawText(screen, sizeX-len(bufferInfoMsg)-1, 0, sizeX-1, 0, topMenuStyle, bufferInfoMsg) } } func getBufferInfoMsg(window *Window) string { pathToFile := "Not set" filename := "Not set" filetype := "Not set" if window.CurrentBuffer.filename != "" { pathToFile = window.CurrentBuffer.filename } if filepath.Base(window.CurrentBuffer.filename) != "." { filename = filepath.Base(window.CurrentBuffer.filename) } if window.CurrentBuffer.filetype != "" { filetype = window.CurrentBuffer.filetype } var contents runestring.RuneString = nil ret := Config.BufferInfoMessage ret = strings.ReplaceAll(ret, "\n", " ") ret = strings.ReplaceAll(ret, "%F", pathToFile) ret = strings.ReplaceAll(ret, "%f", filename) ret = strings.ReplaceAll(ret, "%t", filetype) ret = strings.ReplaceAll(ret, "%x", strconv.Itoa(window.CurrentBuffer.CursorPos.X+1)) ret = strings.ReplaceAll(ret, "%y", strconv.Itoa(window.CurrentBuffer.CursorPos.Y+1)) // Only replace if found for expensive calls if strings.Contains(ret, "%p") { ret = strings.ReplaceAll(ret, "%p", strconv.Itoa(window.CurrentBuffer.PositionToAbsolutePosition(window.CurrentBuffer.CursorPos)+1)) } if strings.Contains(ret, "%c") { contents = window.CurrentBuffer.GetContentsAsString() chars := len(contents) ret = strings.ReplaceAll(ret, "%c", strconv.Itoa(chars)) } if strings.Contains(ret, "%w") { if contents == nil { contents = window.CurrentBuffer.GetContentsAsString() } words := len(strings.Fields(string(contents))) ret = strings.ReplaceAll(ret, "%w", strconv.Itoa(words)) } return ret }