Clean up colors, clean up config, make config actually be used, add default config
This commit is contained in:
84
cmdConfig.go
Normal file
84
cmdConfig.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// +build !rm_basic_commands allcommands setcmd
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
command := Command{
|
||||||
|
Cmd: []string{"config"},
|
||||||
|
Description: "Change various settings",
|
||||||
|
Help: "",
|
||||||
|
Exec: cmdConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterCommand(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdConfig(cmd []string) {
|
||||||
|
var err error
|
||||||
|
switch {
|
||||||
|
case len(cmd) == 2:
|
||||||
|
if cmd[1] == "load" {
|
||||||
|
config, err = readConfig()
|
||||||
|
if err != nil {
|
||||||
|
printError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
printInfoF("Config file loaded: $TEXT", config.Colors.Message.Attachment.stylize(config.filepath))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case len(cmd) > 2:
|
||||||
|
if cmd[1] == "load" {
|
||||||
|
config, err = readConfig(cmd[3])
|
||||||
|
if err != nil {
|
||||||
|
printError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
printInfoF("Config file loaded: $TEXT", config.Colors.Message.Attachment.stylize(config.filepath))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printError("Must pass a valid command")
|
||||||
|
}
|
||||||
|
|
||||||
|
func readConfig(filepath ...string) (*Config, error) {
|
||||||
|
var result = new(Config)
|
||||||
|
var configFile string
|
||||||
|
var env bool
|
||||||
|
|
||||||
|
switch len(filepath) {
|
||||||
|
case 0:
|
||||||
|
configFile, env = os.LookupEnv("KBTUI_CFG")
|
||||||
|
if !env {
|
||||||
|
configFile = "~/.config/kbtui.toml"
|
||||||
|
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
||||||
|
configFile = "kbtui.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
configFile = filepath[0]
|
||||||
|
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
||||||
|
return result, fmt.Errorf("Unable to load config: %s not found", configFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := ioutil.ReadFile(configFile)
|
||||||
|
if err != nil {
|
||||||
|
f = []byte(defaultConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = toml.Unmarshal(f, result)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result.filepath = configFile
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
@ -21,7 +21,7 @@ func init() {
|
|||||||
func cmdDownloadFile(cmd []string) {
|
func cmdDownloadFile(cmd []string) {
|
||||||
|
|
||||||
if len(cmd) < 2 {
|
if len(cmd) < 2 {
|
||||||
printInfo(fmt.Sprintf("%s%s $messageId $fileName - Download a file to user's downloadpath", cmdPrefix, cmd[0]))
|
printInfo(fmt.Sprintf("%s%s $messageId $fileName - Download a file to user's downloadpath", config.Basics.CmdPrefix, cmd[0]))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
messageID, err := strconv.Atoi(cmd[1])
|
messageID, err := strconv.Atoi(cmd[1])
|
||||||
@ -46,8 +46,8 @@ func cmdDownloadFile(cmd []string) {
|
|||||||
fileName = api.Result.Messages[0].Msg.Content.Attachment.Object.Filename
|
fileName = api.Result.Messages[0].Msg.Content.Attachment.Object.Filename
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = chat.Download(messageID, fmt.Sprintf("%s/%s", downloadPath, fileName))
|
_, err = chat.Download(messageID, fmt.Sprintf("%s/%s", config.Basics.DownloadPath, fileName))
|
||||||
channelName := messageLinkKeybaseColor.stylize(channel.Name)
|
channelName := config.Colors.Message.LinkKeybase.stylize(channel.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
printErrorF(fmt.Sprintf("There was an error downloading %s from $TEXT", fileName), channelName)
|
printErrorF(fmt.Sprintf("There was an error downloading %s from $TEXT", fileName), channelName)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -25,7 +25,7 @@ func cmdHelp(cmd []string) {
|
|||||||
if len(cmd) == 1 {
|
if len(cmd) == 1 {
|
||||||
sort.Strings(baseCommands)
|
sort.Strings(baseCommands)
|
||||||
for _, c := range baseCommands {
|
for _, c := range baseCommands {
|
||||||
helpText = fmt.Sprintf("%s%s%s\t\t%s\n", helpText, cmdPrefix, c, commands[c].Description)
|
helpText = fmt.Sprintf("%s%s%s\t\t%s\n", helpText, config.Basics.CmdPrefix, c, commands[c].Description)
|
||||||
}
|
}
|
||||||
if len(typeCommands) > 0 {
|
if len(typeCommands) > 0 {
|
||||||
for c := range typeCommands {
|
for c := range typeCommands {
|
||||||
|
|||||||
@ -41,12 +41,12 @@ func cmdJoin(cmd []string) {
|
|||||||
channel.TopicName = ""
|
channel.TopicName = ""
|
||||||
channel.MembersType = keybase.USER
|
channel.MembersType = keybase.USER
|
||||||
}
|
}
|
||||||
printInfoF("You are joining: $TEXT", messageLinkKeybaseColor.stylize(joinedName))
|
printInfoF("You are joining: $TEXT", config.Colors.Message.LinkKeybase.stylize(joinedName))
|
||||||
clearView("Chat")
|
clearView("Chat")
|
||||||
setViewTitle("Input", fmt.Sprintf(" %s ", joinedName))
|
setViewTitle("Input", fmt.Sprintf(" %s ", joinedName))
|
||||||
go populateChat()
|
go populateChat()
|
||||||
default:
|
default:
|
||||||
printInfo(fmt.Sprintf("To join a team use %sjoin <team> <channel>", cmdPrefix))
|
printInfo(fmt.Sprintf("To join a team use %sjoin <team> <channel>", config.Basics.CmdPrefix))
|
||||||
printInfo(fmt.Sprintf("To join a PM use %sjoin <user>", cmdPrefix))
|
printInfo(fmt.Sprintf("To join a PM use %sjoin <user>", config.Basics.CmdPrefix))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ func init() {
|
|||||||
func cmdReply(cmd []string) {
|
func cmdReply(cmd []string) {
|
||||||
chat := k.NewChat(channel)
|
chat := k.NewChat(channel)
|
||||||
if len(cmd) < 2 {
|
if len(cmd) < 2 {
|
||||||
printInfo(fmt.Sprintf("%s%s $ID - Reply to message $ID", cmdPrefix, cmd[0]))
|
printInfo(fmt.Sprintf("%s%s $ID - Reply to message $ID", config.Basics.CmdPrefix, cmd[0]))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
messageID, err := strconv.Atoi(cmd[1])
|
messageID, err := strconv.Atoi(cmd[1])
|
||||||
|
|||||||
125
cmdSet.go
125
cmdSet.go
@ -1,125 +0,0 @@
|
|||||||
// +build !rm_basic_commands allcommands setcmd
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/pelletier/go-toml"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
command := Command{
|
|
||||||
Cmd: []string{"set", "config"},
|
|
||||||
Description: "Change various settings",
|
|
||||||
Help: "",
|
|
||||||
Exec: cmdSet,
|
|
||||||
}
|
|
||||||
|
|
||||||
RegisterCommand(command)
|
|
||||||
}
|
|
||||||
func printSetting(cmd []string) {
|
|
||||||
switch cmd[1] {
|
|
||||||
case "load":
|
|
||||||
loadFromToml()
|
|
||||||
case "downloadPath":
|
|
||||||
printInfo(fmt.Sprintf("Setting for %s -> %s", cmd[1], downloadPath))
|
|
||||||
case "outputFormat":
|
|
||||||
printInfo(fmt.Sprintf("Setting for %s -> %s", cmd[1], outputFormat))
|
|
||||||
case "dateFormat":
|
|
||||||
printInfo(fmt.Sprintf("Setting for %s -> %s", cmd[1], dateFormat))
|
|
||||||
case "timeFormat":
|
|
||||||
printInfo(fmt.Sprintf("Setting for %s -> %s", cmd[1], timeFormat))
|
|
||||||
case "cmdPrefix":
|
|
||||||
printInfo(fmt.Sprintf("Setting for %s -> %s", cmd[1], cmdPrefix))
|
|
||||||
default:
|
|
||||||
printError(fmt.Sprintf("Unknown config value %s", cmd[1]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func cmdSet(cmd []string) {
|
|
||||||
if len(cmd) < 2 {
|
|
||||||
printError("No config value specified")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(cmd) < 3 {
|
|
||||||
printSetting(cmd)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch cmd[1] {
|
|
||||||
case "downloadPath":
|
|
||||||
if len(cmd) != 3 {
|
|
||||||
printError("Invalid download path.")
|
|
||||||
}
|
|
||||||
downloadPath = cmd[2]
|
|
||||||
case "outputFormat":
|
|
||||||
outputFormat = strings.Join(cmd[1:], " ")
|
|
||||||
case "dateFormat":
|
|
||||||
dateFormat = strings.Join(cmd[1:], " ")
|
|
||||||
case "timeFormat":
|
|
||||||
timeFormat = strings.Join(cmd[1:], " ")
|
|
||||||
case "cmdPrefix":
|
|
||||||
cmdPrefix = cmd[2]
|
|
||||||
default:
|
|
||||||
printError(fmt.Sprintf("Unknown config value %s", cmd[1]))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
func loadFromToml() {
|
|
||||||
configFile, env := os.LookupEnv("KBTUI_CFG")
|
|
||||||
if !env {
|
|
||||||
configFile = "~/.config/kbtui.toml"
|
|
||||||
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
|
||||||
configFile = "kbtui.toml"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
printInfoF("Loading config from toml: $TEXT", messageAttachmentColor.stylize(configFile))
|
|
||||||
config, err := toml.LoadFile(configFile)
|
|
||||||
if err != nil {
|
|
||||||
printError(fmt.Sprintf("Could not read config file: %+v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
colorless = config.GetDefault("Basics.colorless", false).(bool)
|
|
||||||
if config.Has("Basics.colorless") {
|
|
||||||
colorless = config.Get("Basics.colorless").(bool)
|
|
||||||
}
|
|
||||||
if config.Has("Basics.downloadPath") {
|
|
||||||
downloadPath = config.Get("Basics.downloadPath").(string)
|
|
||||||
}
|
|
||||||
if config.Has("Basics.cmdPrefix") {
|
|
||||||
cmdPrefix = config.Get("Basics.cmdPrefix").(string)
|
|
||||||
}
|
|
||||||
if config.Has("Formatting.outputFormat") {
|
|
||||||
outputFormat = config.Get("Formatting.outputFormat").(string)
|
|
||||||
}
|
|
||||||
if config.Has("Formatting.dateFormat") {
|
|
||||||
dateFormat = config.Get("Formatting.dateFormat").(string)
|
|
||||||
}
|
|
||||||
if config.Has("Formatting.timeFormat") {
|
|
||||||
timeFormat = config.Get("Formatting.timeFormat").(string)
|
|
||||||
}
|
|
||||||
channelsColor = styleFromConfig(config, "channels.basic")
|
|
||||||
|
|
||||||
channelsHeaderColor = styleFromConfig(config, "channels.header")
|
|
||||||
channelUnreadColor = styleFromConfig(config, "channels.unread")
|
|
||||||
|
|
||||||
mentionColor = styleFromConfig(config, "message.mention")
|
|
||||||
messageHeaderColor = styleFromConfig(config, "message.header")
|
|
||||||
messageIDColor = styleFromConfig(config, "message.id")
|
|
||||||
messageTimeColor = styleFromConfig(config, "message.time")
|
|
||||||
messageSenderDefaultColor = styleFromConfig(config, "message.sender_default")
|
|
||||||
messageSenderDeviceColor = styleFromConfig(config, "message.sender_device")
|
|
||||||
messageBodyColor = styleFromConfig(config, "message.body")
|
|
||||||
messageAttachmentColor = styleFromConfig(config, "message.attachment")
|
|
||||||
messageLinkURLColor = styleFromConfig(config, "message.link_url")
|
|
||||||
messageLinkKeybaseColor = styleFromConfig(config, "message.link_keybase")
|
|
||||||
messageReactionColor = styleFromConfig(config, "message.reaction")
|
|
||||||
messageCodeColor = styleFromConfig(config, "message.code")
|
|
||||||
|
|
||||||
feedColor = styleFromConfig(config, "feed.basic")
|
|
||||||
errorColor = styleFromConfig(config, "feed.error")
|
|
||||||
|
|
||||||
RunCommand("clean")
|
|
||||||
}
|
|
||||||
@ -22,6 +22,6 @@ func cmdStream(cmd []string) {
|
|||||||
channel.Name = ""
|
channel.Name = ""
|
||||||
|
|
||||||
printInfo("You are now viewing the formatted stream")
|
printInfo("You are now viewing the formatted stream")
|
||||||
setViewTitle("Input", fmt.Sprintf(" Stream - Not in a chat. %sj to join ", cmdPrefix))
|
setViewTitle("Input", fmt.Sprintf(" Stream - Not in a chat. %sj to join ", config.Basics.CmdPrefix))
|
||||||
clearView("Chat")
|
clearView("Chat")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ func init() {
|
|||||||
|
|
||||||
func cmdUploadFile(cmd []string) {
|
func cmdUploadFile(cmd []string) {
|
||||||
if len(cmd) < 2 {
|
if len(cmd) < 2 {
|
||||||
printInfo(fmt.Sprintf("%s%s $filePath $fileName - Upload file from absolute path with optional name", cmdPrefix, cmd[0]))
|
printInfo(fmt.Sprintf("%s%s $filePath $fileName - Upload file from absolute path with optional name", config.Basics.CmdPrefix, cmd[0]))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
filePath := cmd[1]
|
filePath := cmd[1]
|
||||||
@ -40,7 +40,7 @@ func cmdUploadFile(cmd []string) {
|
|||||||
}
|
}
|
||||||
chat := k.NewChat(channel)
|
chat := k.NewChat(channel)
|
||||||
_, err := chat.Upload(fileName, filePath)
|
_, err := chat.Upload(fileName, filePath)
|
||||||
channelName := messageLinkKeybaseColor.stylize(channel.Name).string()
|
channelName := config.Colors.Message.LinkKeybase.stylize(channel.Name).string()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
printError(fmt.Sprintf("There was an error uploading %s to %s\n%+v", filePath, channelName, err))
|
printError(fmt.Sprintf("There was an error uploading %s to %s\n%+v", filePath, channelName, err))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -65,7 +65,7 @@ func cmdPopulateWall(cmd []string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
printInfoF("Displaying public messages for user $TEXT", messageLinkKeybaseColor.stylize(requestedUsers))
|
printInfoF("Displaying public messages for user $TEXT", config.Colors.Message.LinkKeybase.stylize(requestedUsers))
|
||||||
for _, chann := range users {
|
for _, chann := range users {
|
||||||
chat := k.NewChat(chann)
|
chat := k.NewChat(chann)
|
||||||
api, err := chat.Read()
|
api, err := chat.Read()
|
||||||
|
|||||||
151
colors.go
151
colors.go
@ -2,16 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pelletier/go-toml"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Begin Colors
|
|
||||||
type color int
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
black color = iota
|
black int = iota
|
||||||
red
|
red
|
||||||
green
|
green
|
||||||
yellow
|
yellow
|
||||||
@ -19,103 +15,88 @@ const (
|
|||||||
magenta
|
magenta
|
||||||
cyan
|
cyan
|
||||||
grey
|
grey
|
||||||
normal color = -1
|
normal int = -1
|
||||||
)
|
)
|
||||||
|
|
||||||
func colorFromString(s string) color {
|
var colorMapString = map[string]int{
|
||||||
s = strings.ToLower(s)
|
"black": black,
|
||||||
switch s {
|
"red": red,
|
||||||
case "black":
|
"green": green,
|
||||||
return black
|
"yellow": yellow,
|
||||||
case "red":
|
"purple": purple,
|
||||||
return red
|
"magenta": magenta,
|
||||||
case "green":
|
"cyan": cyan,
|
||||||
return green
|
"grey": grey,
|
||||||
case "yellow":
|
"normal": normal,
|
||||||
return yellow
|
}
|
||||||
case "purple":
|
|
||||||
return purple
|
var colorMapInt = map[int]string{
|
||||||
case "magenta":
|
black: "black",
|
||||||
return magenta
|
red: "red",
|
||||||
case "cyan":
|
green: "green",
|
||||||
return cyan
|
yellow: "yellow",
|
||||||
case "grey":
|
purple: "purple",
|
||||||
return grey
|
magenta: "magenta",
|
||||||
case "normal":
|
cyan: "cyan",
|
||||||
|
grey: "grey",
|
||||||
|
normal: "normal",
|
||||||
|
}
|
||||||
|
|
||||||
|
func colorFromString(color string) int {
|
||||||
|
var result int
|
||||||
|
color = strings.ToLower(color)
|
||||||
|
result, ok := colorMapString[color]
|
||||||
|
if !ok {
|
||||||
return normal
|
return normal
|
||||||
default:
|
|
||||||
printError(fmt.Sprintf("color `%s` cannot be parsed.", s))
|
|
||||||
}
|
}
|
||||||
return normal
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Style struct for specializing the style/color of a stylize
|
func colorFromInt(color int) string {
|
||||||
type Style struct {
|
var result string
|
||||||
foregroundColor color
|
result, ok := colorMapInt[color]
|
||||||
backgroundColor color
|
if !ok {
|
||||||
bold bool
|
return "normal"
|
||||||
italic bool // Currently not supported by the UI library
|
}
|
||||||
underline bool
|
return result
|
||||||
strikethrough bool // Currently not supported by the UI library
|
|
||||||
inverse bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var basicStyle = Style{normal, normal, false, false, false, false, false}
|
var basicStyle = Style{
|
||||||
|
Foreground: colorMapInt[normal],
|
||||||
func styleFromConfig(config *toml.Tree, key string) Style {
|
Background: colorMapInt[normal],
|
||||||
key = "Colors." + key + "."
|
Italic: false,
|
||||||
style := basicStyle
|
Bold: false,
|
||||||
if config.Has(key + "foreground") {
|
Underline: false,
|
||||||
style = style.withForeground(colorFromString(config.Get(key + "foreground").(string)))
|
Strikethrough: false,
|
||||||
}
|
Inverse: false,
|
||||||
if config.Has(key + "background") {
|
|
||||||
style = style.withForeground(colorFromString(config.Get(key + "background").(string)))
|
|
||||||
}
|
|
||||||
if config.GetDefault(key+"bold", false).(bool) {
|
|
||||||
style = style.withBold()
|
|
||||||
}
|
|
||||||
if config.GetDefault(key+"italic", false).(bool) {
|
|
||||||
style = style.withItalic()
|
|
||||||
}
|
|
||||||
if config.GetDefault(key+"underline", false).(bool) {
|
|
||||||
style = style.withUnderline()
|
|
||||||
}
|
|
||||||
if config.GetDefault(key+"strikethrough", false).(bool) {
|
|
||||||
style = style.withStrikethrough()
|
|
||||||
}
|
|
||||||
if config.GetDefault(key+"inverse", false).(bool) {
|
|
||||||
style = style.withInverse()
|
|
||||||
}
|
|
||||||
|
|
||||||
return style
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Style) withForeground(f color) Style {
|
func (s Style) withForeground(color int) Style {
|
||||||
s.foregroundColor = f
|
s.Foreground = colorFromInt(color)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (s Style) withBackground(f color) Style {
|
func (s Style) withBackground(color int) Style {
|
||||||
s.backgroundColor = f
|
s.Background = colorFromInt(color)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (s Style) withBold() Style {
|
func (s Style) withBold() Style {
|
||||||
s.bold = true
|
s.Bold = true
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (s Style) withInverse() Style {
|
func (s Style) withInverse() Style {
|
||||||
s.inverse = true
|
s.Inverse = true
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (s Style) withItalic() Style {
|
func (s Style) withItalic() Style {
|
||||||
s.italic = true
|
s.Italic = true
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (s Style) withStrikethrough() Style {
|
func (s Style) withStrikethrough() Style {
|
||||||
s.strikethrough = true
|
s.Strikethrough = true
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (s Style) withUnderline() Style {
|
func (s Style) withUnderline() Style {
|
||||||
s.underline = true
|
s.Underline = true
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,29 +104,29 @@ func (s Style) withUnderline() Style {
|
|||||||
// which essentially just adds on top. that is relevant in the case of
|
// which essentially just adds on top. that is relevant in the case of
|
||||||
// bold/italic etc - it should add style - not clear.
|
// bold/italic etc - it should add style - not clear.
|
||||||
func (s Style) toANSI() string {
|
func (s Style) toANSI() string {
|
||||||
if colorless {
|
if config.Basics.Colorless {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
output := "\x1b[0m\x1b[0"
|
output := "\x1b[0m\x1b[0"
|
||||||
if s.foregroundColor != normal {
|
if colorFromString(s.Foreground) != normal {
|
||||||
output += fmt.Sprintf(";%d", 30+s.foregroundColor)
|
output += fmt.Sprintf(";%d", 30+colorFromString(s.Foreground))
|
||||||
}
|
}
|
||||||
if s.backgroundColor != normal {
|
if colorFromString(s.Background) != normal {
|
||||||
output += fmt.Sprintf(";%d", 40+s.backgroundColor)
|
output += fmt.Sprintf(";%d", 40+colorFromString(s.Background))
|
||||||
}
|
}
|
||||||
if s.bold {
|
if s.Bold {
|
||||||
output += ";1"
|
output += ";1"
|
||||||
}
|
}
|
||||||
if s.italic {
|
if s.Italic {
|
||||||
output += ";3"
|
output += ";3"
|
||||||
}
|
}
|
||||||
if s.underline {
|
if s.Underline {
|
||||||
output += ";4"
|
output += ";4"
|
||||||
}
|
}
|
||||||
if s.inverse {
|
if s.Inverse {
|
||||||
output += ";7"
|
output += ";7"
|
||||||
}
|
}
|
||||||
if s.strikethrough {
|
if s.Strikethrough {
|
||||||
output += ";9"
|
output += ";9"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
70
defaultConfig.go
Normal file
70
defaultConfig.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
var defaultConfig = `
|
||||||
|
[basics]
|
||||||
|
downloadPath = "/tmp/"
|
||||||
|
colorless = false
|
||||||
|
# The prefix before evaluating a command
|
||||||
|
cmdPrefix = "/"
|
||||||
|
|
||||||
|
[formatting]
|
||||||
|
# BASH-like PS1 variable equivalent
|
||||||
|
outputFormat = "┌──[$USER@$DEVICE] [$ID] [$DATE - $TIME]\n└╼ $MSG"
|
||||||
|
outputStreamFormat = "┌──[$USER@$DEVICE] [$ID] [$DATE - $TIME]\n└╼ $MSG"
|
||||||
|
outputMentionFormat = "┌──[$USER@$DEVICE] [$ID] [$DATE - $TIME]\n└╼ $MSG"
|
||||||
|
pmFormat = "PM from $USER@$DEVICE: $MSG"
|
||||||
|
|
||||||
|
# 02 = Day, Jan = Month, 06 = Year
|
||||||
|
dateFormat = "02Jan06"
|
||||||
|
|
||||||
|
# 15 = hours, 04 = minutes, 05 = seconds
|
||||||
|
timeFormat = "15:04"
|
||||||
|
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
[colors.channels]
|
||||||
|
[colors.channels.basic]
|
||||||
|
foreground = "normal"
|
||||||
|
[colors.channels.header]
|
||||||
|
foreground = "magenta"
|
||||||
|
bold = true
|
||||||
|
[colors.channels.unread]
|
||||||
|
foreground = "green"
|
||||||
|
italic = true
|
||||||
|
|
||||||
|
[colors.message]
|
||||||
|
[colors.message.body]
|
||||||
|
foreground = "normal"
|
||||||
|
[colors.message.header]
|
||||||
|
foreground = "grey"
|
||||||
|
[colors.message.mention]
|
||||||
|
foreground = "green"
|
||||||
|
italic = true
|
||||||
|
bold = true
|
||||||
|
[colors.message.id]
|
||||||
|
foreground = "yellow"
|
||||||
|
[colors.message.time]
|
||||||
|
foreground = "magenta"
|
||||||
|
[colors.message.sender_default]
|
||||||
|
foreground = "cyan"
|
||||||
|
bold = true
|
||||||
|
[colors.message.sender_device]
|
||||||
|
foreground = "cyan"
|
||||||
|
[colors.message.attachment]
|
||||||
|
foreground = "red"
|
||||||
|
[colors.message.link_url]
|
||||||
|
foreground = "yellow"
|
||||||
|
[colors.message.link_keybase]
|
||||||
|
foreground = "yellow"
|
||||||
|
[colors.message.reaction]
|
||||||
|
foreground = "magenta"
|
||||||
|
bold = true
|
||||||
|
[colors.message.code]
|
||||||
|
foreground = "cyan"
|
||||||
|
background = "grey"
|
||||||
|
[colors.feed]
|
||||||
|
[colors.feed.basic]
|
||||||
|
foreground = "grey"
|
||||||
|
[colors.feed.error]
|
||||||
|
foreground = "red"
|
||||||
|
`
|
||||||
49
kbtui.toml
49
kbtui.toml
@ -1,12 +1,15 @@
|
|||||||
[Basics]
|
[basics]
|
||||||
downloadPath = "/tmp/"
|
downloadPath = "/tmp/"
|
||||||
colorless = false
|
colorless = false
|
||||||
# The prefix before evaluating a command
|
# The prefix before evaluating a command
|
||||||
cmdPrefix = "/"
|
cmdPrefix = "/"
|
||||||
|
|
||||||
[Formatting]
|
[formatting]
|
||||||
# BASH-like PS1 variable equivalent
|
# BASH-like PS1 variable equivalent
|
||||||
outputFormat = "┌──[$USER@$DEVICE] [$ID] [$DATE - $TIME]\n└╼ $MSG"
|
outputFormat = "┌──[$USER@$DEVICE] [$ID] [$DATE - $TIME]\n└╼ $MSG"
|
||||||
|
outputStreamFormat = "┌──[$USER@$DEVICE] [$ID] [$DATE - $TIME]\n└╼ $MSG"
|
||||||
|
outputMentionFormat = "┌──[$USER@$DEVICE] [$ID] [$DATE - $TIME]\n└╼ $MSG"
|
||||||
|
pmFormat = "PM from $USER@$DEVICE: $MSG"
|
||||||
|
|
||||||
# 02 = Day, Jan = Month, 06 = Year
|
# 02 = Day, Jan = Month, 06 = Year
|
||||||
dateFormat = "02Jan06"
|
dateFormat = "02Jan06"
|
||||||
@ -15,49 +18,49 @@ dateFormat = "02Jan06"
|
|||||||
timeFormat = "15:04"
|
timeFormat = "15:04"
|
||||||
|
|
||||||
|
|
||||||
[Colors]
|
[colors]
|
||||||
[Colors.channels]
|
[colors.channels]
|
||||||
[Colors.channels.basic]
|
[colors.channels.basic]
|
||||||
foreground = "normal"
|
foreground = "normal"
|
||||||
[Colors.channels.header]
|
[colors.channels.header]
|
||||||
foreground = "magenta"
|
foreground = "magenta"
|
||||||
bold = true
|
bold = true
|
||||||
[Colors.channels.unread]
|
[colors.channels.unread]
|
||||||
foreground = "green"
|
foreground = "green"
|
||||||
italic = true
|
italic = true
|
||||||
|
|
||||||
[Colors.message]
|
[colors.message]
|
||||||
[Colors.message.body]
|
[colors.message.body]
|
||||||
foreground = "normal"
|
foreground = "normal"
|
||||||
[Colors.message.header]
|
[colors.message.header]
|
||||||
foreground = "grey"
|
foreground = "grey"
|
||||||
[Colors.message.mention]
|
[colors.message.mention]
|
||||||
foreground = "green"
|
foreground = "green"
|
||||||
italic = true
|
italic = true
|
||||||
bold = true
|
bold = true
|
||||||
[Colors.message.id]
|
[colors.message.id]
|
||||||
foreground = "yellow"
|
foreground = "yellow"
|
||||||
[Colors.message.time]
|
[colors.message.time]
|
||||||
foreground = "magenta"
|
foreground = "magenta"
|
||||||
[Colors.message.sender_default]
|
[colors.message.sender_default]
|
||||||
foreground = "cyan"
|
foreground = "cyan"
|
||||||
bold = true
|
bold = true
|
||||||
[Colors.message.sender_device]
|
[colors.message.sender_device]
|
||||||
foreground = "cyan"
|
foreground = "cyan"
|
||||||
[Colors.message.attachment]
|
[colors.message.attachment]
|
||||||
foreground = "red"
|
foreground = "red"
|
||||||
[Colors.message.link_url]
|
[colors.message.link_url]
|
||||||
foreground = "yellow"
|
foreground = "yellow"
|
||||||
[Colors.message.link_keybase]
|
[colors.message.link_keybase]
|
||||||
foreground = "yellow"
|
foreground = "yellow"
|
||||||
[Colors.message.reaction]
|
[colors.message.reaction]
|
||||||
foreground = "magenta"
|
foreground = "magenta"
|
||||||
bold = true
|
bold = true
|
||||||
[Colors.message.code]
|
[colors.message.code]
|
||||||
foreground = "cyan"
|
foreground = "cyan"
|
||||||
background = "grey"
|
background = "grey"
|
||||||
[Colors.feed]
|
[colors.feed]
|
||||||
[Colors.feed.basic]
|
[colors.feed.basic]
|
||||||
foreground = "grey"
|
foreground = "grey"
|
||||||
[Colors.feed.error]
|
[colors.feed.error]
|
||||||
foreground = "red"
|
foreground = "red"
|
||||||
78
main.go
78
main.go
@ -25,6 +25,8 @@ var (
|
|||||||
g *gocui.Gui
|
g *gocui.Gui
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var config *Config
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if !k.LoggedIn {
|
if !k.LoggedIn {
|
||||||
fmt.Println("You are not logged in.")
|
fmt.Println("You are not logged in.")
|
||||||
@ -37,7 +39,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer g.Close()
|
defer g.Close()
|
||||||
g.SetManagerFunc(layout)
|
g.SetManagerFunc(layout)
|
||||||
go RunCommand("config", "load")
|
RunCommand("config", "load")
|
||||||
go populateList()
|
go populateList()
|
||||||
go updateChatWindow()
|
go updateChatWindow()
|
||||||
if len(os.Args) > 1 {
|
if len(os.Args) > 1 {
|
||||||
@ -82,7 +84,7 @@ func layout(g *gocui.Gui) error {
|
|||||||
chatView.Autoscroll = true
|
chatView.Autoscroll = true
|
||||||
chatView.Wrap = true
|
chatView.Wrap = true
|
||||||
welcomeText := basicStyle.stylize("Welcome $USER!\n\nYour chats will appear here.\nSupported commands are as follows:\n")
|
welcomeText := basicStyle.stylize("Welcome $USER!\n\nYour chats will appear here.\nSupported commands are as follows:\n")
|
||||||
welcomeText = welcomeText.replace("$USER", mentionColor.stylize(k.Username))
|
welcomeText = welcomeText.replace("$USER", config.Colors.Message.Mention.stylize(k.Username))
|
||||||
fmt.Fprintln(chatView, welcomeText.string())
|
fmt.Fprintln(chatView, welcomeText.string())
|
||||||
RunCommand("help")
|
RunCommand("help")
|
||||||
}
|
}
|
||||||
@ -95,7 +97,7 @@ func layout(g *gocui.Gui) error {
|
|||||||
}
|
}
|
||||||
inputView.Editable = true
|
inputView.Editable = true
|
||||||
inputView.Wrap = true
|
inputView.Wrap = true
|
||||||
inputView.Title = fmt.Sprintf(" Not in a chat - write `%sj` to join", cmdPrefix)
|
inputView.Title = fmt.Sprintf(" Not in a chat - write `%sj` to join", config.Basics.CmdPrefix)
|
||||||
g.Cursor = true
|
g.Cursor = true
|
||||||
}
|
}
|
||||||
if listView, err4 := g.SetView("List", 0, 0, maxX/2-maxX/3-1, maxY-1, 0); err4 != nil {
|
if listView, err4 := g.SetView("List", 0, 0, maxX/2-maxX/3-1, maxY-1, 0); err4 != nil {
|
||||||
@ -255,7 +257,7 @@ func printError(message string) {
|
|||||||
printErrorF(message)
|
printErrorF(message)
|
||||||
}
|
}
|
||||||
func printErrorF(message string, parts ...StyledString) {
|
func printErrorF(message string, parts ...StyledString) {
|
||||||
printToView("Feed", errorColor.sprintf(removeFormatting(message), parts...).string())
|
printToView("Feed", config.Colors.Feed.Error.sprintf(removeFormatting(message), parts...).string())
|
||||||
}
|
}
|
||||||
|
|
||||||
// this removes formatting
|
// this removes formatting
|
||||||
@ -265,7 +267,7 @@ func printInfo(message string) {
|
|||||||
|
|
||||||
// this removes formatting
|
// this removes formatting
|
||||||
func printInfoF(message string, parts ...StyledString) {
|
func printInfoF(message string, parts ...StyledString) {
|
||||||
printToView("Feed", feedColor.sprintf(removeFormatting(message), parts...).string())
|
printToView("Feed", config.Colors.Feed.Basic.sprintf(removeFormatting(message), parts...).string())
|
||||||
}
|
}
|
||||||
func printToView(viewName string, message string) {
|
func printToView(viewName string, message string) {
|
||||||
g.Update(func(g *gocui.Gui) error {
|
g.Update(func(g *gocui.Gui) error {
|
||||||
@ -345,10 +347,10 @@ func populateList() {
|
|||||||
log.Printf("%+v", err)
|
log.Printf("%+v", err)
|
||||||
} else {
|
} else {
|
||||||
clearView("List")
|
clearView("List")
|
||||||
var textBase = channelsColor.stylize("")
|
var textBase = config.Colors.Channels.Basic.stylize("")
|
||||||
var recentPMs = textBase.append(channelsHeaderColor.stylize("---[PMs]---\n"))
|
var recentPMs = textBase.append(config.Colors.Channels.Header.stylize("---[PMs]---\n"))
|
||||||
var recentPMsCount = 0
|
var recentPMsCount = 0
|
||||||
var recentChannels = textBase.append(channelsHeaderColor.stylize("---[Teams]---\n"))
|
var recentChannels = textBase.append(config.Colors.Channels.Header.stylize("---[Teams]---\n"))
|
||||||
var recentChannelsCount = 0
|
var recentChannelsCount = 0
|
||||||
for _, s := range testVar.Result.Conversations {
|
for _, s := range testVar.Result.Conversations {
|
||||||
channels = append(channels, s.Channel)
|
channels = append(channels, s.Channel)
|
||||||
@ -357,7 +359,7 @@ func populateList() {
|
|||||||
if recentChannelsCount <= ((maxY - 2) / 3) {
|
if recentChannelsCount <= ((maxY - 2) / 3) {
|
||||||
channel := fmt.Sprintf("%s\n\t#%s\n", s.Channel.Name, s.Channel.TopicName)
|
channel := fmt.Sprintf("%s\n\t#%s\n", s.Channel.Name, s.Channel.TopicName)
|
||||||
if s.Unread {
|
if s.Unread {
|
||||||
recentChannels = recentChannels.append(channelUnreadColor.stylize("*" + channel))
|
recentChannels = recentChannels.append(config.Colors.Channels.Unread.stylize("*" + channel))
|
||||||
} else {
|
} else {
|
||||||
recentChannels = recentChannels.appendString(channel)
|
recentChannels = recentChannels.appendString(channel)
|
||||||
}
|
}
|
||||||
@ -367,7 +369,7 @@ func populateList() {
|
|||||||
if recentPMsCount <= ((maxY - 2) / 3) {
|
if recentPMsCount <= ((maxY - 2) / 3) {
|
||||||
pmName := fmt.Sprintf("%s\n", cleanChannelName(s.Channel.Name))
|
pmName := fmt.Sprintf("%s\n", cleanChannelName(s.Channel.Name))
|
||||||
if s.Unread {
|
if s.Unread {
|
||||||
recentPMs = recentPMs.append(channelUnreadColor.stylize("*" + pmName))
|
recentPMs = recentPMs.append(config.Colors.Channels.Unread.stylize("*" + pmName))
|
||||||
} else {
|
} else {
|
||||||
recentPMs = recentPMs.appendString(pmName)
|
recentPMs = recentPMs.appendString(pmName)
|
||||||
}
|
}
|
||||||
@ -384,35 +386,35 @@ func populateList() {
|
|||||||
|
|
||||||
// Formatting
|
// Formatting
|
||||||
func formatMessageBody(body string) StyledString {
|
func formatMessageBody(body string) StyledString {
|
||||||
output := messageBodyColor.stylize(body)
|
output := config.Colors.Message.Body.stylize(body)
|
||||||
|
|
||||||
output = colorReplaceMentionMe(output)
|
output = colorReplaceMentionMe(output)
|
||||||
output = output.colorRegex(`_[^_]*_`, messageBodyColor.withItalic())
|
output = output.colorRegex(`_[^_]*_`, config.Colors.Message.Body.withItalic())
|
||||||
output = output.colorRegex(`~[^~]*~`, messageBodyColor.withStrikethrough())
|
output = output.colorRegex(`~[^~]*~`, config.Colors.Message.Body.withStrikethrough())
|
||||||
output = output.colorRegex(`@[\w_]*(\.[\w_]+)*`, messageLinkKeybaseColor)
|
output = output.colorRegex(`@[\w_]*(\.[\w_]+)*`, config.Colors.Message.LinkKeybase)
|
||||||
// TODO change how bold, italic etc works, so it uses boldOn boldOff ([1m and [22m)
|
// TODO change how bold, italic etc works, so it uses boldOn boldOff ([1m and [22m)
|
||||||
output = output.colorRegex(`\*[^\*]*\*`, messageBodyColor.withBold())
|
output = output.colorRegex(`\*[^\*]*\*`, config.Colors.Message.Body.withBold())
|
||||||
output = output.replaceString("```", "<code>")
|
output = output.replaceString("```", "<code>")
|
||||||
// TODO make background color cover whole line
|
// TODO make background color cover whole line
|
||||||
output = output.colorRegex("<code>(.*\n)*<code>", messageCodeColor)
|
output = output.colorRegex("<code>(.*\n)*<code>", config.Colors.Message.Code)
|
||||||
output = output.colorRegex("`[^`]*`", messageCodeColor)
|
output = output.colorRegex("`[^`]*`", config.Colors.Message.Code)
|
||||||
// mention URL
|
// mention URL
|
||||||
output = output.colorRegex(`(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*))`, messageLinkURLColor)
|
output = output.colorRegex(`(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*))`, config.Colors.Message.LinkURL)
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO use this more
|
// TODO use this more
|
||||||
func formatChannel(ch keybase.Channel) StyledString {
|
func formatChannel(ch keybase.Channel) StyledString {
|
||||||
return messageLinkKeybaseColor.stylize(fmt.Sprintf("@%s#%s", ch.Name, ch.TopicName))
|
return config.Colors.Message.LinkKeybase.stylize(fmt.Sprintf("@%s#%s", ch.Name, ch.TopicName))
|
||||||
}
|
}
|
||||||
|
|
||||||
func colorReplaceMentionMe(msg StyledString) StyledString {
|
func colorReplaceMentionMe(msg StyledString) StyledString {
|
||||||
return msg.colorRegex("(@?"+k.Username+")", mentionColor)
|
return msg.colorRegex("(@?"+k.Username+")", config.Colors.Message.Mention)
|
||||||
}
|
}
|
||||||
func colorUsername(username string) StyledString {
|
func colorUsername(username string) StyledString {
|
||||||
var color = messageSenderDefaultColor
|
var color = config.Colors.Message.SenderDefault
|
||||||
if username == k.Username {
|
if username == k.Username {
|
||||||
color = mentionColor
|
color = config.Colors.Message.Mention
|
||||||
}
|
}
|
||||||
return color.stylize(username)
|
return color.stylize(username)
|
||||||
}
|
}
|
||||||
@ -423,27 +425,27 @@ func cleanChannelName(c string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func formatMessage(api keybase.ChatAPI, formatString string) string {
|
func formatMessage(api keybase.ChatAPI, formatString string) string {
|
||||||
ret := messageHeaderColor.stylize("")
|
ret := config.Colors.Message.Header.stylize("")
|
||||||
msgType := api.Msg.Content.Type
|
msgType := api.Msg.Content.Type
|
||||||
switch msgType {
|
switch msgType {
|
||||||
case "text", "attachment":
|
case "text", "attachment":
|
||||||
ret = messageHeaderColor.stylize(formatString)
|
ret = config.Colors.Message.Header.stylize(formatString)
|
||||||
tm := time.Unix(int64(api.Msg.SentAt), 0)
|
tm := time.Unix(int64(api.Msg.SentAt), 0)
|
||||||
var msg = formatMessageBody(api.Msg.Content.Text.Body)
|
var msg = formatMessageBody(api.Msg.Content.Text.Body)
|
||||||
if msgType == "attachment" {
|
if msgType == "attachment" {
|
||||||
msg = messageBodyColor.stylize("$TITLE\n$FILE")
|
msg = config.Colors.Message.Body.stylize("$TITLE\n$FILE")
|
||||||
attachment := api.Msg.Content.Attachment
|
attachment := api.Msg.Content.Attachment
|
||||||
msg = msg.replaceString("$TITLE", attachment.Object.Title)
|
msg = msg.replaceString("$TITLE", attachment.Object.Title)
|
||||||
msg = msg.replace("$FILE", messageAttachmentColor.stylize(fmt.Sprintf("[Attachment: %s]", attachment.Object.Filename)))
|
msg = msg.replace("$FILE", config.Colors.Message.Attachment.stylize(fmt.Sprintf("[Attachment: %s]", attachment.Object.Filename)))
|
||||||
}
|
}
|
||||||
|
|
||||||
user := colorUsername(api.Msg.Sender.Username)
|
user := colorUsername(api.Msg.Sender.Username)
|
||||||
device := messageSenderDeviceColor.stylize(api.Msg.Sender.DeviceName)
|
device := config.Colors.Message.SenderDevice.stylize(api.Msg.Sender.DeviceName)
|
||||||
msgID := messageIDColor.stylize(fmt.Sprintf("%d", api.Msg.ID))
|
msgID := config.Colors.Message.ID.stylize(fmt.Sprintf("%d", api.Msg.ID))
|
||||||
date := messageTimeColor.stylize(tm.Format(dateFormat))
|
date := config.Colors.Message.Time.stylize(tm.Format(config.Formatting.DateFormat))
|
||||||
msgTime := messageTimeColor.stylize(tm.Format(timeFormat))
|
msgTime := config.Colors.Message.Time.stylize(tm.Format(config.Formatting.TimeFormat))
|
||||||
|
|
||||||
channelName := messageIDColor.stylize(fmt.Sprintf("@%s#%s", api.Msg.Channel.Name, api.Msg.Channel.TopicName))
|
channelName := config.Colors.Message.ID.stylize(fmt.Sprintf("@%s#%s", api.Msg.Channel.Name, api.Msg.Channel.TopicName))
|
||||||
ret = ret.replace("$MSG", msg)
|
ret = ret.replace("$MSG", msg)
|
||||||
ret = ret.replace("$USER", user)
|
ret = ret.replace("$USER", user)
|
||||||
ret = ret.replace("$DEVICE", device)
|
ret = ret.replace("$DEVICE", device)
|
||||||
@ -455,9 +457,9 @@ func formatMessage(api keybase.ChatAPI, formatString string) string {
|
|||||||
return ret.string()
|
return ret.string()
|
||||||
}
|
}
|
||||||
func formatOutput(api keybase.ChatAPI) string {
|
func formatOutput(api keybase.ChatAPI) string {
|
||||||
format := outputFormat
|
format := config.Formatting.OutputFormat
|
||||||
if stream {
|
if stream {
|
||||||
format = outputStreamFormat
|
format = config.Formatting.OutputStreamFormat
|
||||||
}
|
}
|
||||||
return formatMessage(api, format)
|
return formatMessage(api, format)
|
||||||
}
|
}
|
||||||
@ -485,7 +487,7 @@ func handleMessage(api keybase.ChatAPI) {
|
|||||||
if m.Text == k.Username {
|
if m.Text == k.Username {
|
||||||
// We are in a team
|
// We are in a team
|
||||||
if topicName != channel.TopicName {
|
if topicName != channel.TopicName {
|
||||||
printInfo(formatMessage(api, mentionFormat))
|
printInfo(formatMessage(api, config.Formatting.OutputMentionFormat))
|
||||||
fmt.Print("\a")
|
fmt.Print("\a")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,7 +496,7 @@ func handleMessage(api keybase.ChatAPI) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if msgSender != channel.Name {
|
if msgSender != channel.Name {
|
||||||
printInfo(formatMessage(api, pmFormat))
|
printInfo(formatMessage(api, config.Formatting.PMFormat))
|
||||||
fmt.Print("\a")
|
fmt.Print("\a")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,7 +514,7 @@ func handleMessage(api keybase.ChatAPI) {
|
|||||||
if api.Msg.Channel.MembersType == keybase.TEAM {
|
if api.Msg.Channel.MembersType == keybase.TEAM {
|
||||||
printToView("Chat", formatOutput(api))
|
printToView("Chat", formatOutput(api))
|
||||||
} else {
|
} else {
|
||||||
printToView("Chat", formatMessage(api, pmFormat))
|
printToView("Chat", formatMessage(api, config.Formatting.PMFormat))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -546,8 +548,8 @@ func handleInput(viewName string) error {
|
|||||||
if inputString == "" {
|
if inputString == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(inputString, cmdPrefix) {
|
if strings.HasPrefix(inputString, config.Basics.CmdPrefix) {
|
||||||
cmd := deleteEmpty(strings.Split(inputString[len(cmdPrefix):], " "))
|
cmd := deleteEmpty(strings.Split(inputString[len(config.Basics.CmdPrefix):], " "))
|
||||||
if len(cmd) < 1 {
|
if len(cmd) < 1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,9 +22,9 @@ func init() {
|
|||||||
func tcmdShowReactions(m keybase.ChatAPI) {
|
func tcmdShowReactions(m keybase.ChatAPI) {
|
||||||
team := false
|
team := false
|
||||||
user := colorUsername(m.Msg.Sender.Username)
|
user := colorUsername(m.Msg.Sender.Username)
|
||||||
id := messageIDColor.stylize(fmt.Sprintf("%d", m.Msg.Content.Reaction.M))
|
id := config.Colors.Message.ID.stylize(fmt.Sprintf("%d", m.Msg.Content.Reaction.M))
|
||||||
reaction := messageReactionColor.stylize(m.Msg.Content.Reaction.B)
|
reaction := config.Colors.Message.Reaction.stylize(m.Msg.Content.Reaction.B)
|
||||||
where := messageLinkKeybaseColor.stylize("a PM")
|
where := config.Colors.Message.LinkKeybase.stylize("a PM")
|
||||||
if m.Msg.Channel.MembersType == keybase.TEAM {
|
if m.Msg.Channel.MembersType == keybase.TEAM {
|
||||||
team = true
|
team = true
|
||||||
where = formatChannel(m.Msg.Channel)
|
where = formatChannel(m.Msg.Channel)
|
||||||
|
|||||||
65
types.go
65
types.go
@ -17,3 +17,68 @@ type TypeCommand struct {
|
|||||||
Description string // A short description of the command
|
Description string // A short description of the command
|
||||||
Exec func(keybase.ChatAPI) // A function that takes a raw chat message as input
|
Exec func(keybase.ChatAPI) // A function that takes a raw chat message as input
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Config holds user-configurable values
|
||||||
|
type Config struct {
|
||||||
|
filepath string `toml:"-"`
|
||||||
|
Basics Basics `toml:"basics"`
|
||||||
|
Formatting Formatting `toml:"formatting"`
|
||||||
|
Colors Colors `toml:"colors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Basics struct {
|
||||||
|
DownloadPath string `toml:"downloadPath"`
|
||||||
|
Colorless bool `toml:"colorless"`
|
||||||
|
CmdPrefix string `toml:"cmdPrefix"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Formatting struct {
|
||||||
|
OutputFormat string `toml:"outputFormat"`
|
||||||
|
OutputStreamFormat string `toml:"outputStreamFormat"`
|
||||||
|
OutputMentionFormat string `toml:"outputMentionFormat"`
|
||||||
|
PMFormat string `toml:"pmFormat"`
|
||||||
|
DateFormat string `toml:"dateFormat"`
|
||||||
|
TimeFormat string `toml:"timeFormat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Style struct {
|
||||||
|
Foreground string `toml:"foreground"`
|
||||||
|
Background string `toml:"background"`
|
||||||
|
Italic bool `toml:"italic"`
|
||||||
|
Bold bool `toml:"bold"`
|
||||||
|
Underline bool `toml:"underline"`
|
||||||
|
Strikethrough bool `toml:"strikethrough"`
|
||||||
|
Inverse bool `toml:"inverse"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Channels struct {
|
||||||
|
Basic Style `toml:"basic"`
|
||||||
|
Header Style `toml:"header"`
|
||||||
|
Unread Style `toml:"unread"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Body Style `toml:"body"`
|
||||||
|
Header Style `toml:"header"`
|
||||||
|
Mention Style `toml:"mention"`
|
||||||
|
ID Style `toml:"id"`
|
||||||
|
Time Style `toml:"time"`
|
||||||
|
SenderDefault Style `toml:"sender_default"`
|
||||||
|
SenderDevice Style `toml:"sender_device"`
|
||||||
|
Attachment Style `toml:"attachment"`
|
||||||
|
LinkURL Style `toml:"link_url"`
|
||||||
|
LinkKeybase Style `toml:"link_keybase"`
|
||||||
|
Reaction Style `toml:"reaction"`
|
||||||
|
Code Style `toml:"code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Feed struct {
|
||||||
|
Basic Style `toml:"basic"`
|
||||||
|
Error Style `toml:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Colors struct {
|
||||||
|
Channels Channels `toml:"channels"`
|
||||||
|
Message Message `toml:"message"`
|
||||||
|
Feed Feed `toml:"feed"`
|
||||||
|
}
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// Path where Downloaded files will default to
|
|
||||||
var downloadPath = "/tmp/"
|
|
||||||
|
|
||||||
var colorless bool = false
|
|
||||||
var channelsColor = basicStyle
|
|
||||||
var channelUnreadColor = channelsColor.withForeground(green).withItalic()
|
|
||||||
var channelsHeaderColor = channelsColor.withForeground(magenta).withBold()
|
|
||||||
|
|
||||||
var mentionColor = basicStyle.withForeground(green)
|
|
||||||
var messageHeaderColor = basicStyle.withForeground(grey)
|
|
||||||
var messageIDColor = basicStyle.withForeground(yellow)
|
|
||||||
var messageTimeColor = basicStyle.withForeground(magenta)
|
|
||||||
var messageSenderDefaultColor = basicStyle.withForeground(cyan)
|
|
||||||
var messageSenderDeviceColor = messageSenderDefaultColor
|
|
||||||
var messageBodyColor = basicStyle
|
|
||||||
var messageAttachmentColor = basicStyle.withForeground(red)
|
|
||||||
var messageLinkURLColor = basicStyle.withForeground(yellow)
|
|
||||||
var messageLinkKeybaseColor = basicStyle.withForeground(yellow)
|
|
||||||
var messageReactionColor = basicStyle.withForeground(magenta)
|
|
||||||
var messageCodeColor = basicStyle.withBackground(grey).withForeground(cyan)
|
|
||||||
|
|
||||||
var feedColor = basicStyle.withForeground(grey)
|
|
||||||
var errorColor = basicStyle.withForeground(red)
|
|
||||||
|
|
||||||
// BASH-like PS1 variable equivalent
|
|
||||||
var outputFormat = "┌──[$USER@$DEVICE] [$ID] [$DATE - $TIME]\n└╼ $MSG"
|
|
||||||
var outputStreamFormat = "┌──[$TEAM] [$USER@$DEVICE] [$ID] [$DATE - $TIME]\n└╼ $MSG"
|
|
||||||
var mentionFormat = outputStreamFormat
|
|
||||||
var pmFormat = "PM from $USER@$DEVICE: $MSG"
|
|
||||||
|
|
||||||
// 02 = Day, Jan = Month, 06 = Year
|
|
||||||
var dateFormat = "02Jan06"
|
|
||||||
|
|
||||||
// 15 = hours, 04 = minutes, 05 = seconds
|
|
||||||
var timeFormat = "15:04"
|
|
||||||
|
|
||||||
// The prefix before evaluating a command
|
|
||||||
var cmdPrefix = "/"
|
|
||||||
Reference in New Issue
Block a user