parent
692773a23f
commit
cee4e6b6af
13
README.md
13
README.md
@ -59,6 +59,16 @@ Getting started
|
||||
"C-8": "backspace",
|
||||
"<delete>": "delete",
|
||||
"<space>": "space"
|
||||
},
|
||||
"search": {
|
||||
"<left>": "cursor-left",
|
||||
"<right>": "cursor-right",
|
||||
"<escape>": "clear-input",
|
||||
"<enter>": "clear-input",
|
||||
"<backspace>": "backspace",
|
||||
"C-8": "backspace",
|
||||
"<delete>": "delete",
|
||||
"<space>": "space"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -79,6 +89,7 @@ Default Key Mapping
|
||||
| mode | key | action |
|
||||
|---------|-----------|----------------------------|
|
||||
| command | `i` | insert mode |
|
||||
| command | `/` | search mode |
|
||||
| command | `k` | move channel cursor up |
|
||||
| command | `j` | move channel cursor down |
|
||||
| command | `g` | move channel cursor top |
|
||||
@ -95,3 +106,5 @@ Default Key Mapping
|
||||
| insert | `right` | move input cursor right |
|
||||
| insert | `enter` | send message |
|
||||
| insert | `esc` | command mode |
|
||||
| search | `esc` | command mode |
|
||||
| search | `enter` | command mode |
|
||||
|
@ -195,6 +195,7 @@ func (c *Channels) MoveCursorBottom() {
|
||||
|
||||
// ScrollUp enables us to scroll through the channel list when it overflows
|
||||
func (c *Channels) ScrollUp() {
|
||||
// Is cursor at the top of the channel view?
|
||||
if c.CursorPosition == c.List.InnerBounds().Min.Y {
|
||||
if c.Offset > 0 {
|
||||
c.Offset--
|
||||
@ -206,6 +207,7 @@ func (c *Channels) ScrollUp() {
|
||||
|
||||
// ScrollDown enables us to scroll through the channel list when it overflows
|
||||
func (c *Channels) ScrollDown() {
|
||||
// Is the cursor at the bottom of the channel view?
|
||||
if c.CursorPosition == c.List.InnerBounds().Max.Y-1 {
|
||||
if c.Offset < len(c.List.Items)-1 {
|
||||
c.Offset++
|
||||
@ -215,6 +217,45 @@ func (c *Channels) ScrollDown() {
|
||||
}
|
||||
}
|
||||
|
||||
// Search will search through the channels to find a channel,
|
||||
// when a match has been found the selected channel will then
|
||||
// be the channel that has been found
|
||||
func (c *Channels) Search(term string) {
|
||||
for i, item := range c.List.Items {
|
||||
if strings.Contains(item, term) {
|
||||
|
||||
// The new position
|
||||
newPos := i
|
||||
|
||||
// Is the new position in range of the current view?
|
||||
minRange := c.Offset
|
||||
maxRange := c.Offset + c.List.InnerBounds().Max.Y - 1
|
||||
|
||||
if newPos < minRange {
|
||||
// newPos is above, we need to scroll up.
|
||||
c.SetSelectedChannel(i)
|
||||
|
||||
// How much do we need to scroll to get it into range?
|
||||
c.Offset = c.Offset - (minRange - newPos)
|
||||
} else if newPos > maxRange {
|
||||
// newPos is below, we need to scroll down
|
||||
c.SetSelectedChannel(i)
|
||||
|
||||
// How much do we need to scroll to get it into range?
|
||||
c.Offset = c.Offset + (newPos - maxRange) + 1
|
||||
} else {
|
||||
// newPos is inside range
|
||||
c.SetSelectedChannel(i)
|
||||
}
|
||||
|
||||
// Set cursor to correct position
|
||||
c.CursorPosition = (newPos - minRange) + 1
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetNotification will be called when a new message arrives and will
|
||||
// render an notification icon in front of the channel name
|
||||
func (c *Channels) SetNotification(svc *service.SlackService, channelID string) {
|
||||
|
@ -28,6 +28,7 @@ func NewConfig(filepath string) (*Config, error) {
|
||||
KeyMap: map[string]keyMapping{
|
||||
"command": {
|
||||
"i": "mode-insert",
|
||||
"/": "mode-search",
|
||||
"k": "channel-up",
|
||||
"j": "channel-down",
|
||||
"g": "channel-top",
|
||||
@ -51,6 +52,16 @@ func NewConfig(filepath string) (*Config, error) {
|
||||
"<delete>": "delete",
|
||||
"<space>": "space",
|
||||
},
|
||||
"search": {
|
||||
"<left>": "cursor-left",
|
||||
"<right>": "cursor-right",
|
||||
"<escape>": "clear-input",
|
||||
"<enter>": "clear-input",
|
||||
"<backspace>": "backspace",
|
||||
"C-8": "backspace",
|
||||
"<delete>": "delete",
|
||||
"<space>": "space",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
const (
|
||||
CommandMode = "command"
|
||||
InsertMode = "insert"
|
||||
SearchMode = "search"
|
||||
)
|
||||
|
||||
type AppContext struct {
|
||||
|
@ -28,6 +28,8 @@ var actionMap = map[string]func(*context.AppContext){
|
||||
"quit": actionQuit,
|
||||
"mode-insert": actionInsertMode,
|
||||
"mode-command": actionCommandMode,
|
||||
"mode-search": actionSearchMode,
|
||||
"clear-input": actionClearInput,
|
||||
"channel-up": actionMoveCursorUpChannels,
|
||||
"channel-down": actionMoveCursorDownChannels,
|
||||
"channel-top": actionMoveCursorTopChannels,
|
||||
@ -67,6 +69,8 @@ func anyKeyHandler(ctx *context.AppContext) {
|
||||
} else {
|
||||
if ctx.Mode == context.InsertMode && ev.Ch != 0 {
|
||||
actionInput(ctx.View, ev.Ch)
|
||||
} else if ctx.Mode == context.SearchMode && ev.Ch != 0 {
|
||||
actionSearch(ctx, ev.Ch)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,6 +137,15 @@ func actionInput(view *views.View, key rune) {
|
||||
termui.Render(view.Input)
|
||||
}
|
||||
|
||||
func actionClearInput(ctx *context.AppContext) {
|
||||
// Clear input
|
||||
ctx.View.Input.Clear()
|
||||
ctx.View.Refresh()
|
||||
|
||||
// Set command mode
|
||||
actionCommandMode(ctx)
|
||||
}
|
||||
|
||||
func actionSpace(ctx *context.AppContext) {
|
||||
actionInput(ctx.View, ' ')
|
||||
}
|
||||
@ -174,6 +187,23 @@ func actionSend(ctx *context.AppContext) {
|
||||
}
|
||||
}
|
||||
|
||||
func actionSearch(ctx *context.AppContext, key rune) {
|
||||
go func() {
|
||||
if timer != nil {
|
||||
timer.Stop()
|
||||
}
|
||||
|
||||
actionInput(ctx.View, key)
|
||||
|
||||
timer = time.NewTimer(time.Second / 4)
|
||||
<-timer.C
|
||||
|
||||
term := ctx.View.Input.GetText()
|
||||
ctx.View.Channels.Search(term)
|
||||
actionChangeChannel(ctx)
|
||||
}()
|
||||
}
|
||||
|
||||
// actionQuit will exit the program by using os.Exit, this is
|
||||
// done because we are using a custom termui EvtStream. Which
|
||||
// we won't be able to call termui.StopLoop() on. See main.go
|
||||
@ -194,6 +224,12 @@ func actionCommandMode(ctx *context.AppContext) {
|
||||
termui.Render(ctx.View.Mode)
|
||||
}
|
||||
|
||||
func actionSearchMode(ctx *context.AppContext) {
|
||||
ctx.Mode = context.SearchMode
|
||||
ctx.View.Mode.Par.Text = "SEARCH"
|
||||
termui.Render(ctx.View.Mode)
|
||||
}
|
||||
|
||||
func actionGetMessages(ctx *context.AppContext) {
|
||||
ctx.View.Chat.GetMessages(
|
||||
ctx.Service,
|
||||
|
Loading…
Reference in New Issue
Block a user