diff options
author | Richard Burke <rich.g.burke@gmail.com> | 2019-01-10 21:50:45 +0000 |
---|---|---|
committer | Richard Burke <rich.g.burke@gmail.com> | 2019-01-10 21:50:45 +0000 |
commit | d75371247500183e4a1478292632abff60c0613b (patch) | |
tree | cfd027231cc75bb0dd7ef930dae5e9e65b56f3b1 | |
parent | f6990a7abff56d6b382833fc4caf70c793d1c120 (diff) |
Added sleep command
-rw-r--r-- | cmd/grv/config.go | 11 | ||||
-rw-r--r-- | cmd/grv/config_command_help.go | 21 | ||||
-rw-r--r-- | cmd/grv/config_parse.go | 30 | ||||
-rw-r--r-- | cmd/grv/config_parse_test.go | 27 | ||||
-rw-r--r-- | cmd/grv/grv.go | 21 | ||||
-rw-r--r-- | cmd/grv/key_bindings.go | 5 | ||||
-rw-r--r-- | doc/documentation.md | 17 |
7 files changed, 131 insertions, 1 deletions
diff --git a/cmd/grv/config.go b/cmd/grv/config.go index e54402e..fdb9275 100644 --- a/cmd/grv/config.go +++ b/cmd/grv/config.go @@ -538,6 +538,8 @@ func (config *Configuration) processCommand(command ConfigCommand, inputSource s err = config.processCustomCommand(command) case *EvalKeysCommand: err = config.processEvalKeysCommand(command) + case *SleepCommand: + err = config.processSleepCommand(command) default: log.Errorf("Unknown command type %T", command) } @@ -958,6 +960,15 @@ func (config *Configuration) processEvalKeysCommand(evalKeysCommand *EvalKeysCom return } +func (config *Configuration) processSleepCommand(sleepCommand *SleepCommand) (err error) { + config.channels.DoAction(Action{ + ActionType: ActionSleep, + Args: []interface{}{sleepCommand.sleepSeconds}, + }) + + return +} + func (config *Configuration) runCommand(command string, outputType ShellCommandOutputType) { NewShellCommandProcessor(config.channels, config.variables, command, outputType).Execute() } diff --git a/cmd/grv/config_command_help.go b/cmd/grv/config_command_help.go index e5825b9..2f5e076 100644 --- a/cmd/grv/config_command_help.go +++ b/cmd/grv/config_command_help.go @@ -467,7 +467,28 @@ func GenerateEvalKeysCommandHelpSections(config Config) (helpSections []*HelpSec {text: "For example, running the following will switch to the next tab:"}, {}, {text: "evalkeys <grv-next-tab>", themeComponentID: CmpHelpViewSectionCodeBlock}, + } + + return []*HelpSection{ + { + description: description, + }, + } +} + +// GenerateSleepCommandHelpSections generates help documentation for the addtab command +func GenerateSleepCommandHelpSections(config Config) (helpSections []*HelpSection) { + description := []HelpSectionText{ + {text: "sleep", themeComponentID: CmpHelpViewSectionSubTitle}, + {}, + {text: "The sleep command causes grv to pause execution for the provided number of seconds."}, + {text: "The format of the command is:"}, + {}, + {text: "sleep seconds", themeComponentID: CmpHelpViewSectionCodeBlock}, + {}, + {text: "For example, running the following will pause execution for 0.5 seconds:"}, {}, + {text: "sleep 0.5", themeComponentID: CmpHelpViewSectionCodeBlock}, } return []*HelpSection{ diff --git a/cmd/grv/config_parse.go b/cmd/grv/config_parse.go index 8261640..5b5db19 100644 --- a/cmd/grv/config_parse.go +++ b/cmd/grv/config_parse.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "regexp" + "strconv" "strings" "unicode" @@ -30,6 +31,7 @@ const ( defCommand = "def" undefCommand = "undef" evalkeysCommand = "evalkeys" + sleepCommand = "sleep" ) const ( @@ -179,6 +181,13 @@ type EvalKeysCommand struct { func (evalKeysCommand *EvalKeysCommand) configCommand() {} +// SleepCommand represents a command to sleep +type SleepCommand struct { + sleepSeconds float64 +} + +func (sleepCommand *SleepCommand) configCommand() {} + type commandHelpGenerator func(config Config) []*HelpSection type commandCustomParser func(parser *ConfigParser) (tokens []*ConfigToken, err error) @@ -299,6 +308,11 @@ var commandDescriptors = map[string]*commandDescriptor{ constructor: evalKeysCommandConstructor, commandHelpGenerator: GenerateEvalKeysCommandHelpSections, }, + sleepCommand: { + tokenTypes: []ConfigTokenType{CtkWord}, + constructor: sleepCommandConstructor, + commandHelpGenerator: GenerateSleepCommandHelpSections, + }, } // GenerateConfigCommandHelpSections generates help documentation for all configuration commands @@ -769,3 +783,19 @@ func evalKeysCommandConstructor(parser *ConfigParser, commandToken *ConfigToken, keys: keys, }, nil } + +func sleepCommandConstructor(parser *ConfigParser, commandToken *ConfigToken, tokens []*ConfigToken) (configCommand ConfigCommand, err error) { + if len(tokens) < 1 { + return nil, parser.generateParseError(commandToken, "No sleep time specified") + } + + sleepToken := tokens[0] + sleepSeconds, err := strconv.ParseFloat(sleepToken.value, 64) + if err != nil || sleepSeconds <= 0.0 { + return nil, parser.generateParseError(sleepToken, "Invalid sleep time: %v. Must be a positive integer", sleepToken.value) + } + + return &SleepCommand{ + sleepSeconds: sleepSeconds, + }, nil +} diff --git a/cmd/grv/config_parse_test.go b/cmd/grv/config_parse_test.go index a95deb5..6fb0dd4 100644 --- a/cmd/grv/config_parse_test.go +++ b/cmd/grv/config_parse_test.go @@ -309,6 +309,23 @@ func (evalKeysCommandValues *EvalKeysCommandValues) Equal(command ConfigCommand) return evalKeysCommandValues.keys == other.keys } +type SleepCommandValues struct { + sleepSeconds float64 +} + +func (sleepCommandValues *SleepCommandValues) Equal(command ConfigCommand) bool { + if command == nil { + return false + } + + other, ok := command.(*SleepCommand) + if !ok { + return false + } + + return sleepCommandValues.sleepSeconds == other.sleepSeconds +} + func TestParseSingleCommand(t *testing.T) { var singleCommandTests = []struct { input string @@ -462,6 +479,12 @@ func TestParseSingleCommand(t *testing.T) { keys: "<grv-next-tab><grv-search-prompt>Untracked files<Enter>", }, }, + { + input: "sleep 0.5", + expectedCommand: &SleepCommandValues{ + sleepSeconds: 0.5, + }, + }, } for _, singleCommandTest := range singleCommandTests { @@ -614,6 +637,10 @@ func TestErrorsAreReceivedForInvalidConfigTokenSequences(t *testing.T) { input: "def myfunc { addview RefView ", expectedErrorMessage: ConfigFile + ":1:29 Expected } but reached EOF", }, + { + input: "sleep -5", + expectedErrorMessage: ConfigFile + ":1:7 Invalid sleep time: -5. Must be a positive integer", + }, } for _, errorTest := range errorTests { diff --git a/cmd/grv/grv.go b/cmd/grv/grv.go index 1b71a29..393e45b 100644 --- a/cmd/grv/grv.go +++ b/cmd/grv/grv.go @@ -485,6 +485,10 @@ func (grv *GRV) runHandlerLoop(waitGroup *sync.WaitGroup, exitCh <-chan bool, in if err := grv.runCommand(action); err != nil { errorCh <- err } + case ActionSleep: + if err := grv.sleep(action); err != nil { + errorCh <- err + } default: if err := grv.view.HandleAction(action); err != nil { errorCh <- err @@ -585,6 +589,23 @@ func (grv *GRV) runCommand(action Action) (err error) { return } +func (grv *GRV) sleep(action Action) (err error) { + if len(action.Args) == 0 { + return fmt.Errorf("Expected sleep seconds argument") + } + + sleepSeconds, ok := action.Args[0].(float64) + if !ok { + return fmt.Errorf("Expected sleep seconds of type float64 but found type %T", action.Args[0]) + } + + log.Infof("Sleeping for %v seconds", sleepSeconds) + time.Sleep(time.Duration(sleepSeconds*1000) * time.Millisecond) + log.Infof("Finished sleeping") + + return +} + func (grv *GRV) runSignalHandlerLoop(waitGroup *sync.WaitGroup, exitCh <-chan bool) { defer waitGroup.Done() defer log.Info("Signal handler loop stopping") diff --git a/cmd/grv/key_bindings.go b/cmd/grv/key_bindings.go index dc839c4..8a9fdcb 100644 --- a/cmd/grv/key_bindings.go +++ b/cmd/grv/key_bindings.go @@ -30,6 +30,7 @@ const ( ActionExit ActionSuspend ActionRunCommand + ActionSleep ActionPrompt ActionSearchPrompt ActionReverseSearchPrompt @@ -148,6 +149,10 @@ var actionDescriptors = map[ActionType]ActionDescriptor{ actionCategory: ActionCategoryGeneral, description: "Run a shell command", }, + ActionSleep: { + actionCategory: ActionCategoryGeneral, + description: "Sleep for a specified time", + }, ActionPrompt: { actionKey: "<grv-prompt>", actionCategory: ActionCategoryGeneral, diff --git a/doc/documentation.md b/doc/documentation.md index edcb981..3991721 100644 --- a/doc/documentation.md +++ b/doc/documentation.md @@ -37,6 +37,7 @@ The sections below provide an overview of the ways to configure and interact wit * [q](#q) * [rmtab](#rmtab) * [set](#set) + * [sleep](#sleep) * [split](#split) * [theme](#theme) * [undef](#undef) @@ -350,7 +351,6 @@ For example, running the following will switch to the next tab: evalkeys <grv-next-tab> ``` - ### git The git command is an alias to the git cli command. @@ -467,6 +467,21 @@ GRV currently has the following themes available: The solarized theme is the default theme for GRV and does not respect the terminals colour palette. The classic and cold themes do respect the terminals colour palette. +### sleep + +The sleep command causes grv to pause execution for the provided number of seconds. +The format of the command is: + +``` +sleep seconds +``` + +For example, running the following will pause execution for 0.5 seconds: + +``` +sleep 0.5 +``` + ### split The split command is similar to the vsplit and hsplit commands. |