From 077aff092851310f042e7ec18ee19681afcdfa82 Mon Sep 17 00:00:00 2001 From: Gregory Rudolph Date: Wed, 16 Oct 2019 19:34:50 -0400 Subject: [PATCH] Cleaning up --- main.go | 444 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 222 insertions(+), 222 deletions(-) diff --git a/main.go b/main.go index 13dfcc0..64cce3c 100644 --- a/main.go +++ b/main.go @@ -12,17 +12,19 @@ import ( "samhofi.us/x/keybase" ) -var typeCommands = make(map[string]TypeCommand) -var commands = make(map[string]Command) -var baseCommands = make([]string, 0) - -var dev = false -var k = keybase.NewKeybase() -var channel keybase.Channel -var channels []keybase.Channel -var stream = false -var lastMessage keybase.ChatAPI -var g *gocui.Gui +var ( + typeCommands = make(map[string]TypeCommand) + commands = make(map[string]Command) + baseCommands = make([]string, 0) + + dev = false + k = keybase.NewKeybase() + channel keybase.Channel + channels []keybase.Channel + stream = false + lastMessage keybase.ChatAPI + g *gocui.Gui +) func main() { if !k.LoggedIn { @@ -52,6 +54,99 @@ func main() { } } +// Gocui basic setup +func layout(g *gocui.Gui) error { + maxX, maxY := g.Size() + if editView, err := g.SetView("Edit", maxX/2-maxX/3+1, maxY/2, maxX-2, maxY/2+10, 0); err != nil { + if !gocui.IsUnknownView(err) { + return err + } + editView.Editable = true + editView.Wrap = true + fmt.Fprintln(editView, "Edit window. Should disappear") + } + if feedView, err := g.SetView("Feed", maxX/2-maxX/3, 0, maxX-1, maxY/5, 0); err != nil { + if !gocui.IsUnknownView(err) { + return err + } + feedView.Autoscroll = true + feedView.Wrap = true + feedView.Title = "Feed Window" + fmt.Fprintln(feedView, "Feed Window - If you are mentioned or receive a PM it will show here") + } + if chatView, err2 := g.SetView("Chat", maxX/2-maxX/3, maxY/5+1, maxX-1, maxY-5, 0); err2 != nil { + if !gocui.IsUnknownView(err2) { + return err2 + } + chatView.Autoscroll = true + chatView.Wrap = true + fmt.Fprintf(chatView, "Welcome %s!\n\nYour chats will appear here.\nSupported commands are as follows:\n\n", k.Username) + RunCommand("help") + } + if inputView, err3 := g.SetView("Input", maxX/2-maxX/3, maxY-4, maxX-1, maxY-1, 0); err3 != nil { + if !gocui.IsUnknownView(err3) { + return err3 + } + if _, err := g.SetCurrentView("Input"); err != nil { + return err + } + inputView.Editable = true + inputView.Wrap = true + inputView.Title = fmt.Sprintf(" Not in a chat - write `%sj` to join", cmdPrefix) + g.Cursor = true + } + if listView, err4 := g.SetView("List", 0, 0, maxX/2-maxX/3-1, maxY-1, 0); err4 != nil { + if !gocui.IsUnknownView(err4) { + return err4 + } + listView.Title = "Channels" + fmt.Fprintf(listView, "Lists\nWindow\nTo view\n activity") + } + return nil +} +func initKeybindings() error { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, + func(g *gocui.Gui, v *gocui.View) error { + input, err := getInputString("Input") + if err != nil { + return err + } + if input != "" { + clearView("Input") + return nil + } else { + return gocui.ErrQuit + } + }); err != nil { + return err + } + if err := g.SetKeybinding("Input", gocui.KeyEnter, gocui.ModNone, + func(g *gocui.Gui, v *gocui.View) error { + return handleInput("Input") + }); err != nil { + return err + } + if err := g.SetKeybinding("Input", gocui.KeyTab, gocui.ModNone, + func(g *gocui.Gui, v *gocui.View) error { + return handleTab() + }); err != nil { + return err + } + if err := g.SetKeybinding("Edit", gocui.KeyEnter, gocui.ModNone, + func(g *gocui.Gui, v *gocui.View) error { + popupView("Chat") + popupView("Input") + return handleInput("Edit") + + }); err != nil { + return err + } + return nil +} + +// End gocui basic setup + +// Gocui helper funcs func setViewTitle(viewName string, title string) { g.Update(func(g *gocui.Gui) error { updatingView, err := g.View(viewName) @@ -63,7 +158,6 @@ func setViewTitle(viewName string, title string) { return nil }) } - func getViewTitle(viewName string) string { view, err := g.View(viewName) if err != nil { @@ -74,7 +168,6 @@ func getViewTitle(viewName string) string { return strings.Split(view.Title, "||")[0] } } - func popupView(viewName string) { _, err := g.SetCurrentView(viewName) if err != nil { @@ -96,7 +189,59 @@ func popupView(viewName string) { }) } +func clearView(viewName string) { + g.Update(func(g *gocui.Gui) error { + inputView, err := g.View(viewName) + if err != nil { + return err + } else { + inputView.Clear() + inputView.SetCursor(0, 0) + inputView.SetOrigin(0, 0) + } + return nil + }) + +} +func writeToView(viewName string, message string) { + g.Update(func(g *gocui.Gui) error { + updatingView, err := g.View(viewName) + if err != nil { + return err + } else { + for _, c := range message { + updatingView.EditWrite(c) + } + } + return nil + }) +} +func printToView(viewName string, message string) { + g.Update(func(g *gocui.Gui) error { + updatingView, err := g.View(viewName) + if err != nil { + return err + } else { + fmt.Fprintf(updatingView, "%s\n", message) + } + return nil + }) +} + +// End gocui helper funcs + +// Update/Populate views automatically +func updateChatWindow() { + runOpts := keybase.RunOptions{ + Dev: dev, + } + k.Run(func(api keybase.ChatAPI) { + handleMessage(api) + }, + runOpts) + +} func populateChat() { lastMessage.ID = 0 chat := k.NewChat(channel) @@ -144,14 +289,49 @@ func populateChat() { printToView("Chat", actuallyPrintMe) } +func populateList() { + _, maxY := g.Size() + if testVar, err := k.ChatList(); err != nil { + log.Printf("%+v", err) + } else { -func sendChat(message string) { - chat := k.NewChat(channel) - _, err := chat.Send(message) - if err != nil { - printToView("Feed", fmt.Sprintf("There was an error %+v", err)) + clearView("List") + var recentPMs = fmt.Sprintf("%s---[PMs]---%s\n", channelsHeaderColor, channelsColor) + var recentPMsCount = 0 + var recentChannels = fmt.Sprintf("%s---[Teams]---%s\n", channelsHeaderColor, channelsColor) + var recentChannelsCount = 0 + for _, s := range testVar.Result.Conversations { + channels = append(channels, s.Channel) + if s.Channel.MembersType == keybase.TEAM { + recentChannelsCount++ + if recentChannelsCount <= ((maxY - 2) / 3) { + if s.Unread { + recentChannels += fmt.Sprintf("%s*", color(0)) + } + recentChannels += fmt.Sprintf("%s\n\t#%s\n%s", s.Channel.Name, s.Channel.TopicName, channelsColor) + } + } else { + recentPMsCount++ + if recentPMsCount <= ((maxY - 2) / 3) { + if s.Unread { + recentChannels += fmt.Sprintf("%s*", color(0)) + } + recentPMs += fmt.Sprintf("%s\n%s", cleanChannelName(s.Channel.Name), channelsColor) + } + } + } + time.Sleep(1 * time.Millisecond) + printToView("List", fmt.Sprintf("%s%s%s%s", channelsColor, recentPMs, recentChannels, noColor)) } } + +// End update/populate views automatically + +// Formatting +func cleanChannelName(c string) string { + newChannelName := strings.Replace(c, fmt.Sprintf("%s,", k.Username), "", 1) + return strings.Replace(newChannelName, fmt.Sprintf(",%s", k.Username), "", 1) +} func formatOutput(api keybase.ChatAPI) string { ret := "" msgType := api.Msg.Content.Type @@ -185,42 +365,9 @@ func formatOutput(api keybase.ChatAPI) string { return ret } -func populateList() { - _, maxY := g.Size() - if testVar, err := k.ChatList(); err != nil { - log.Printf("%+v", err) - } else { - - clearView("List") - var recentPMs = fmt.Sprintf("%s---[PMs]---%s\n", channelsHeaderColor, channelsColor) - var recentPMsCount = 0 - var recentChannels = fmt.Sprintf("%s---[Teams]---%s\n", channelsHeaderColor, channelsColor) - var recentChannelsCount = 0 - for _, s := range testVar.Result.Conversations { - channels = append(channels, s.Channel) - if s.Channel.MembersType == keybase.TEAM { - recentChannelsCount++ - if recentChannelsCount <= ((maxY - 2) / 3) { - if s.Unread { - recentChannels += fmt.Sprintf("%s*", color(0)) - } - recentChannels += fmt.Sprintf("%s\n\t#%s\n%s", s.Channel.Name, s.Channel.TopicName, channelsColor) - } - } else { - recentPMsCount++ - if recentPMsCount <= ((maxY - 2) / 3) { - if s.Unread { - recentChannels += fmt.Sprintf("%s*", color(0)) - } - recentPMs += fmt.Sprintf("%s\n%s", cleanChannelName(s.Channel.Name), channelsColor) - } - } - } - time.Sleep(1 * time.Millisecond) - printToView("List", fmt.Sprintf("%s%s%s%s", channelsColor, recentPMs, recentChannels, noColor)) - } -} +// End formatting +// Tab completion func getCurrentChannelMembership() []string { var rs []string if channel.Name != "" { @@ -244,7 +391,6 @@ func getCurrentChannelMembership() []string { } return rs } - func filterStringSlice(ss []string, fv string) []string { var rs []string for _, s := range ss { @@ -254,7 +400,6 @@ func filterStringSlice(ss []string, fv string) []string { } return rs } - func longestCommonPrefix(ss []string) string { // cover the case where the slice has no or one members switch len(ss) { @@ -283,7 +428,6 @@ func longestCommonPrefix(ss []string) string { // to cover the case where all members are equal, just return one return min } - func stringRemainder(aStr, bStr string) string { var long, short string //figure out which string is longer @@ -307,7 +451,6 @@ func stringRemainder(aStr, bStr string) string { // return whatever's left of the longer string return long[i:] } - func appendIfNotInSlice(ss []string, s string) []string { for _, element := range ss { if element == s { @@ -316,7 +459,6 @@ func appendIfNotInSlice(ss []string, s string) []string { } return append(ss, s) } - func generateChannelTabCompletionSlice(inputWord string) []string { // create a slice to hold the values var firstSlice []string @@ -340,13 +482,11 @@ func generateChannelTabCompletionSlice(inputWord string) []string { resultSlice := filterStringSlice(firstSlice, inputWord) return resultSlice } - func generateEmojiTabCompletionSlice(inputWord string) []string { // use the emojiSlice from emojiList.go and filter it for the input word resultSlice := filterStringSlice(emojiSlice, inputWord) return resultSlice } - func handleTab() error { inputString, err := getInputString("Input") if err != nil { @@ -390,164 +530,9 @@ func handleTab() error { return nil } -func clearView(viewName string) { - g.Update(func(g *gocui.Gui) error { - inputView, err := g.View(viewName) - if err != nil { - return err - } else { - inputView.Clear() - inputView.SetCursor(0, 0) - inputView.SetOrigin(0, 0) - } - return nil - }) - -} - -func writeToView(viewName string, message string) { - g.Update(func(g *gocui.Gui) error { - updatingView, err := g.View(viewName) - if err != nil { - return err - } else { - for _, c := range message { - updatingView.EditWrite(c) - } - } - return nil - }) -} - -func printToView(viewName string, message string) { - g.Update(func(g *gocui.Gui) error { - updatingView, err := g.View(viewName) - if err != nil { - return err - } else { - fmt.Fprintf(updatingView, "%s\n", message) - } - return nil - }) -} - -func layout(g *gocui.Gui) error { - maxX, maxY := g.Size() - if editView, err := g.SetView("Edit", maxX/2-maxX/3+1, maxY/2, maxX-2, maxY/2+10, 0); err != nil { - if !gocui.IsUnknownView(err) { - return err - } - editView.Editable = true - editView.Wrap = true - fmt.Fprintln(editView, "Edit window. Should disappear") - } - if feedView, err := g.SetView("Feed", maxX/2-maxX/3, 0, maxX-1, maxY/5, 0); err != nil { - if !gocui.IsUnknownView(err) { - return err - } - feedView.Autoscroll = true - feedView.Wrap = true - feedView.Title = "Feed Window" - fmt.Fprintln(feedView, "Feed Window - If you are mentioned or receive a PM it will show here") - } - if chatView, err2 := g.SetView("Chat", maxX/2-maxX/3, maxY/5+1, maxX-1, maxY-5, 0); err2 != nil { - if !gocui.IsUnknownView(err2) { - return err2 - } - chatView.Autoscroll = true - chatView.Wrap = true - fmt.Fprintf(chatView, "Welcome %s!\n\nYour chats will appear here.\nSupported commands are as follows:\n\n", k.Username) - RunCommand("help") - } - if inputView, err3 := g.SetView("Input", maxX/2-maxX/3, maxY-4, maxX-1, maxY-1, 0); err3 != nil { - if !gocui.IsUnknownView(err3) { - return err3 - } - if _, err := g.SetCurrentView("Input"); err != nil { - return err - } - inputView.Editable = true - inputView.Wrap = true - inputView.Title = fmt.Sprintf(" Not in a chat - write `%sj` to join", cmdPrefix) - g.Cursor = true - } - if listView, err4 := g.SetView("List", 0, 0, maxX/2-maxX/3-1, maxY-1, 0); err4 != nil { - if !gocui.IsUnknownView(err4) { - return err4 - } - listView.Title = "Channels" - fmt.Fprintf(listView, "Lists\nWindow\nTo view\n activity") - } - return nil -} - -func getInputString(viewName string) (string, error) { - inputView, err := g.View(viewName) - if err != nil { - return "", err - } - retString := inputView.Buffer() - retString = strings.Replace(retString, "\n", "", 800) - return retString, err -} - -func initKeybindings() error { - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, - func(g *gocui.Gui, v *gocui.View) error { - input, err := getInputString("Input") - if err != nil { - return err - } - if input != "" { - clearView("Input") - return nil - } else { - return gocui.ErrQuit - } - }); err != nil { - return err - } - if err := g.SetKeybinding("Input", gocui.KeyEnter, gocui.ModNone, - func(g *gocui.Gui, v *gocui.View) error { - return handleInput("Input") - }); err != nil { - return err - } - if err := g.SetKeybinding("Input", gocui.KeyTab, gocui.ModNone, - func(g *gocui.Gui, v *gocui.View) error { - return handleTab() - }); err != nil { - return err - } - if err := g.SetKeybinding("Edit", gocui.KeyEnter, gocui.ModNone, - func(g *gocui.Gui, v *gocui.View) error { - popupView("Chat") - popupView("Input") - return handleInput("Edit") - - }); err != nil { - return err - } - return nil -} - -func updateChatWindow() { - - runOpts := keybase.RunOptions{ - Dev: dev, - } - k.Run(func(api keybase.ChatAPI) { - handleMessage(api) - }, - runOpts) - -} - -func cleanChannelName(c string) string { - newChannelName := strings.Replace(c, fmt.Sprintf("%s,", k.Username), "", 1) - return strings.Replace(newChannelName, fmt.Sprintf(",%s", k.Username), "", 1) -} +// End tab completion +// Input handling func handleMessage(api keybase.ChatAPI) { if _, ok := typeCommands[api.Msg.Content.Type]; ok { if api.Msg.Channel.MembersType == channel.MembersType && cleanChannelName(api.Msg.Channel.Name) == channel.Name { @@ -612,9 +597,16 @@ func handleMessage(api keybase.ChatAPI) { } } } - -// It seems that golang doesn't have filter and other high order functions :'( -func delete_empty(s []string) []string { +func getInputString(viewName string) (string, error) { + inputView, err := g.View(viewName) + if err != nil { + return "", err + } + retString := inputView.Buffer() + retString = strings.Replace(retString, "\n", "", 800) + return retString, err +} +func deleteEmpty(s []string) []string { var r []string for _, str := range s { if str != "" { @@ -623,7 +615,6 @@ func delete_empty(s []string) []string { } return r } - func handleInput(viewName string) error { clearView(viewName) inputString, _ := getInputString(viewName) @@ -631,7 +622,7 @@ func handleInput(viewName string) error { return nil } if strings.HasPrefix(inputString, cmdPrefix) { - cmd := delete_empty(strings.Split(inputString[len(cmdPrefix):], " ")) + cmd := deleteEmpty(strings.Split(inputString[len(cmdPrefix):], " ")) if c, ok := commands[cmd[0]]; ok { c.Exec(cmd) return nil @@ -656,6 +647,15 @@ func handleInput(viewName string) error { go populateList() return nil } +func sendChat(message string) { + chat := k.NewChat(channel) + _, err := chat.Send(message) + if err != nil { + printToView("Feed", fmt.Sprintf("There was an error %+v", err)) + } +} + +// End input handling func quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit