diff --git a/Makefile b/Makefile index 4fe53f20f..2c8b6a997 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ build: mlr: go build github.com/johnkerl/miller/cmd/mlr +# For interactive use, 'mlr regtest' offers more options and transparency. check: unit_test regression_test # Unit tests (small number) diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt index 56201690b..08db5cd67 100644 --- a/docs/src/manpage.txt +++ b/docs/src/manpage.txt @@ -151,11 +151,10 @@ HELP OPTIONS mlr -F = mlr help usage-functions mlr -k = mlr help list-keywords mlr -K = mlr help usage-keywords - Lastly, 'mlr help ...' will search for your text '...' using the sources of + Lastly, 'mlr help ...' will search for your exact text '...' using the sources of 'mlr help flag', 'mlr help verb', 'mlr help function', and 'mlr help keyword'. - For things appearing in more than one place, e.g. 'sec2gmt' which is the name of a - verb as well as a function, use `mlr help verb sec2gmt' or `mlr help function sec2gmt' - to disambiguate. + Use 'mlr help find ...' for approximate (substring) matches, e.g. 'mlr help find map' + for all things with "map" in their names. VERB LIST altkv bar bootstrap cat check clean-whitespace count-distinct count @@ -2959,4 +2958,4 @@ SEE ALSO - 2021-11-15 MILLER(1) + 2021-11-18 MILLER(1) diff --git a/docs/src/online-help.md b/docs/src/online-help.md index cce2cdde2..4bea51ab4 100644 --- a/docs/src/online-help.md +++ b/docs/src/online-help.md @@ -90,18 +90,70 @@ Shorthands: mlr -F = mlr help usage-functions mlr -k = mlr help list-keywords mlr -K = mlr help usage-keywords -Lastly, 'mlr help ...' will search for your text '...' using the sources of +Lastly, 'mlr help ...' will search for your exact text '...' using the sources of 'mlr help flag', 'mlr help verb', 'mlr help function', and 'mlr help keyword'. -For things appearing in more than one place, e.g. 'sec2gmt' which is the name of a -verb as well as a function, use `mlr help verb sec2gmt' or `mlr help function sec2gmt' -to disambiguate. +Use 'mlr help find ...' for approximate (substring) matches, e.g. 'mlr help find map' +for all things with "map" in their names. +If you know the name of the thing you're looking for, use `mlr help`: +
-mlr help functions +mlr help map
-No help found for "functions" -- please try 'mlr help topics'.
+map: declares an map-valued local variable in the current curly-braced scope.
+Type-checking happens at assignment: 'map b = 0' is an error. map b = {} is
+always OK. map b = a is OK or not depending on whether a is a map.
+
+
+To search by substring, use `mlr help find`:
+
++mlr help find gmt ++
+sec2gmtdate
+Usage: ../c/mlr sec2gmtdate {comma-separated list of field names}
+Replaces a numeric field representing seconds since the epoch with the
+corresponding GMT year-month-day timestamp; leaves non-numbers as-is.
+This is nothing more than a keystroke-saver for the sec2gmtdate function:
+ ../c/mlr sec2gmtdate time1,time2
+is the same as
+ ../c/mlr put '$time1=sec2gmtdate($time1);$time2=sec2gmtdate($time2)'
+sec2gmt
+Usage: mlr sec2gmt [options] {comma-separated list of field names}
+Replaces a numeric field representing seconds since the epoch with the
+corresponding GMT timestamp; leaves non-numbers as-is. This is nothing
+more than a keystroke-saver for the sec2gmt function:
+ mlr sec2gmt time1,time2
+is the same as
+ mlr put '$time1 = sec2gmt($time1); $time2 = sec2gmt($time2)'
+Options:
+-1 through -9: format the seconds using 1..9 decimal places, respectively.
+--millis Input numbers are treated as milliseconds since the epoch.
+--micros Input numbers are treated as microseconds since the epoch.
+--nanos Input numbers are treated as nanoseconds since the epoch.
+-h|--help Show this message.
+gmt2localtime (class=time #args=1,2) Convert from a GMT-time string to a local-time string. Consulting $TZ unless second argument is supplied.
+Examples:
+gmt2localtime("1999-12-31T22:00:00Z") = "2000-01-01 00:00:00" with TZ="Asia/Istanbul"
+gmt2localtime("1999-12-31T22:00:00Z", "Asia/Istanbul") = "2000-01-01 00:00:00"
+gmt2sec (class=time #args=1) Parses GMT timestamp as integer seconds since the epoch.
+Example:
+gmt2sec("2001-02-03T04:05:06Z") = 981173106
+localtime2gmt (class=time #args=1,2) Convert from a local-time string to a GMT-time string. Consults $TZ unless second argument is supplied.
+Examples:
+localtime2gmt("2000-01-01 00:00:00") = "1999-12-31T22:00:00Z" with TZ="Asia/Istanbul"
+localtime2gmt("2000-01-01 00:00:00", "Asia/Istanbul") = "1999-12-31T22:00:00Z"
+sec2gmt (class=time #args=1,2) Formats seconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part.
+Examples:
+sec2gmt(1234567890) = "2009-02-13T23:31:30Z"
+sec2gmt(1234567890.123456) = "2009-02-13T23:31:30Z"
+sec2gmt(1234567890.123456, 6) = "2009-02-13T23:31:30.123456Z"
+sec2gmtdate (class=time #args=1) Formats seconds since epoch (integer part) as GMT timestamp with year-month-date. Leaves non-numbers as-is.
+Example:
+sec2gmtdate(1440768801.7) = "2015-08-28".
Etc.
@@ -143,6 +195,7 @@ Options:
mlr help verb sort
+sort
Usage: mlr sort {flags}
Sorts records primarily by the first specified field, secondarily by the second
field, and so on. (Any records not having all specified sort keys will appear
@@ -180,18 +233,9 @@ Given the name of a DSL function (from `mlr -f`) you can use `mlr help function`
append (class=collections #args=2) Appends second argument to end of first argument, which must be an array.
-+mlr help function split--No exact match for "split". Inexact matches: - splita - splitax - splitkv - splitkvx - splitnv - splitnvx -mlr help function splita diff --git a/docs/src/online-help.md.in b/docs/src/online-help.md.in index e75ebf2dd..1b51c8ddb 100644 --- a/docs/src/online-help.md.in +++ b/docs/src/online-help.md.in @@ -14,8 +14,16 @@ GENMD-RUN-COMMAND mlr help topics GENMD-EOF +If you know the name of the thing you're looking for, use `mlr help`: + GENMD-RUN-COMMAND -mlr help functions +mlr help map +GENMD-EOF + +To search by substring, use `mlr help find`: + +GENMD-RUN-COMMAND +mlr help find gmt GENMD-EOF Etc. diff --git a/internal/pkg/auxents/help/entry.go b/internal/pkg/auxents/help/entry.go index 93f8ea9db..7e8c14597 100644 --- a/internal/pkg/auxents/help/entry.go +++ b/internal/pkg/auxents/help/entry.go @@ -19,7 +19,7 @@ import ( // ================================================================ type tZaryHandlerFunc func() -type tUnaryHandlerFunc func(arg string) +type tVarArgHandlerFunc func(args []string) type tHandlerLookupTable struct { sections []tHandlerInfoSection @@ -35,9 +35,9 @@ type tHandlerInfoSection struct { } type tHandlerInfo struct { - name string - zaryHandlerFunc tZaryHandlerFunc - unaryHandlerFunc tUnaryHandlerFunc + name string + zaryHandlerFunc tZaryHandlerFunc + varArgHandlerFunc tVarArgHandlerFunc } type tShorthandTable struct { @@ -80,7 +80,7 @@ func init() { handlerInfos: []tHandlerInfo{ {name: "list-verbs", zaryHandlerFunc: listVerbs}, {name: "usage-verbs", zaryHandlerFunc: usageVerbs}, - {name: "verb", unaryHandlerFunc: helpForVerb}, + {name: "verb", varArgHandlerFunc: helpForVerb}, }, }, { @@ -88,10 +88,10 @@ func init() { handlerInfos: []tHandlerInfo{ {name: "list-functions", zaryHandlerFunc: listFunctions}, {name: "list-function-classes", zaryHandlerFunc: listFunctionClasses}, - {name: "list-functions-in-class", unaryHandlerFunc: listFunctionsInClass}, + {name: "list-functions-in-class", varArgHandlerFunc: listFunctionsInClass}, {name: "usage-functions", zaryHandlerFunc: usageFunctions}, {name: "usage-functions-by-class", zaryHandlerFunc: usageFunctionsByClass}, - {name: "function", unaryHandlerFunc: helpForFunction}, + {name: "function", varArgHandlerFunc: helpForFunction}, }, }, { @@ -99,7 +99,7 @@ func init() { handlerInfos: []tHandlerInfo{ {name: "list-keywords", zaryHandlerFunc: listKeywords}, {name: "usage-keywords", zaryHandlerFunc: usageKeywords}, - {name: "keyword", unaryHandlerFunc: helpForKeyword}, + {name: "keyword", varArgHandlerFunc: helpForKeyword}, }, }, { @@ -117,16 +117,16 @@ func init() { handlerInfos: []tHandlerInfo{ {name: "flag-table-nil-check", zaryHandlerFunc: flagTableNilCheck}, {name: "list-flag-sections", zaryHandlerFunc: listFlagSections}, - {name: "list-flags-for-section", unaryHandlerFunc: listFlagsForSection}, + {name: "list-flags-for-section", varArgHandlerFunc: listFlagsForSection}, {name: "list-functions-as-paragraph", zaryHandlerFunc: listFunctionsAsParagraph}, {name: "list-functions-as-table", zaryHandlerFunc: listFunctionsAsTable}, {name: "list-keywords-as-paragraph", zaryHandlerFunc: listKeywordsAsParagraph}, {name: "list-verbs-as-paragraph", zaryHandlerFunc: listVerbsAsParagraph}, - {name: "print-info-for-section", unaryHandlerFunc: printInfoForSection}, - {name: "show-headline-for-flag", unaryHandlerFunc: showHeadlineForFlag}, - {name: "show-help-for-flag", unaryHandlerFunc: showHelpForFlag}, - {name: "show-help-for-section", unaryHandlerFunc: showHelpForSection}, - {name: "show-help-for-section-via-downdash", unaryHandlerFunc: showHelpForSectionViaDowndash}, + {name: "print-info-for-section", varArgHandlerFunc: printInfoForSection}, + {name: "show-headline-for-flag", varArgHandlerFunc: showHeadlineForFlag}, + {name: "show-help-for-flag", varArgHandlerFunc: showHelpForFlag}, + {name: "show-help-for-section", varArgHandlerFunc: showHelpForSection}, + {name: "show-help-for-section-via-downdash", varArgHandlerFunc: showHelpForSectionViaDowndash}, }, }, }, @@ -158,7 +158,7 @@ func init() { name: downdashSectionName, // Make a function which passes in "csv-only-flags" etc. to the FLAG_TABLE. zaryHandlerFunc: func() { - showHelpForSectionViaDowndash(downdashSectionName) + showHelpForSectionViaDowndash([]string{downdashSectionName}) }, } handlerLookupTable.sections[i].handlerInfos = append(handlerLookupTable.sections[i].handlerInfos, entry) @@ -193,6 +193,19 @@ func HelpMain(args []string) int { return 0 } + // 'mlr help find x' searches for all things (flags, transformers, + // functions, keywords) with an "x" in their name, as a substring. + if args[0] == "find" { + args = args[1:] + if len(args) > 0 { + helpByApproximateSearch(args) + return 0 + } else { + fmt.Printf("mlr help find: need one or more things to search for.\n") + return 1 + } + } + // "mlr help something" where we recognize the something name := args[0] for _, section := range handlerLookupTable.sections { @@ -206,26 +219,23 @@ func HelpMain(args []string) int { info.zaryHandlerFunc() return 0 } - if info.unaryHandlerFunc != nil { + if info.varArgHandlerFunc != nil { if len(args) < 2 { fmt.Printf("mlr help %s takes at least one required argument.\n", name) return 0 } - for _, arg := range args[1:] { - info.unaryHandlerFunc(arg) - } + info.varArgHandlerFunc(args[1:]) return 0 } } } } - if helpBySearch(name) { + // 'mlr help x' searches for all things (flags, transformers, functions, keywords) named "x". + if helpByExactSearch(args) { return 0 } - // "mlr help something" where we do not recognize the something - fmt.Printf("No help found for \"%s\" -- please try 'mlr help topics'.\n", name) return 0 } @@ -289,11 +299,10 @@ func listTopics() { for _, info := range shorthandLookupTable.shorthandInfos { fmt.Printf(" mlr %s = mlr help %s\n", info.shorthand, info.longhand) } - fmt.Printf("Lastly, 'mlr help ...' will search for your text '...' using the sources of\n") + fmt.Printf("Lastly, 'mlr help ...' will search for your exact text '...' using the sources of\n") fmt.Printf("'mlr help flag', 'mlr help verb', 'mlr help function', and 'mlr help keyword'.\n") - fmt.Printf("For things appearing in more than one place, e.g. 'sec2gmt' which is the name of a\n") - fmt.Printf("verb as well as a function, use `mlr help verb sec2gmt' or `mlr help function sec2gmt'\n") - fmt.Printf("to disambiguate.\n") + fmt.Printf("Use 'mlr help find ...' for approximate (substring) matches, e.g. 'mlr help find map'\n") + fmt.Printf("for all things with \"map\" in their names.\n") } // ---------------------------------------------------------------- @@ -482,51 +491,63 @@ func listFlagSections() { cli.FLAG_TABLE.ListFlagSections() } -func printInfoForSection(sectionName string) { - if !cli.FLAG_TABLE.PrintInfoForSection(sectionName) { - fmt.Printf( - "mlr: flag-section \"%s\" not found. Please use \"mlr help list-flag-sections\" for a list.\n", - sectionName) +func printInfoForSection(sectionNames []string) { + for _, sectionName := range sectionNames { + if !cli.FLAG_TABLE.PrintInfoForSection(sectionName) { + fmt.Printf( + "mlr: flag-section \"%s\" not found. Please use \"mlr help list-flag-sections\" for a list.\n", + sectionName) + } } } -func listFlagsForSection(sectionName string) { - if !cli.FLAG_TABLE.ListFlagsForSection(sectionName) { - fmt.Printf( - "mlr: flag-section \"%s\" not found. Please use \"mlr help list-flag-sections\" for a list.\n", - sectionName) +func listFlagsForSection(sectionNames []string) { + for _, sectionName := range sectionNames { + if !cli.FLAG_TABLE.ListFlagsForSection(sectionName) { + fmt.Printf( + "mlr: flag-section \"%s\" not found. Please use \"mlr help list-flag-sections\" for a list.\n", + sectionName) + } } } // For manpage autogen: just produce text -func showHelpForSection(sectionName string) { - if !cli.FLAG_TABLE.ShowHelpForSection(sectionName) { - fmt.Printf( - "mlr: flag-section \"%s\" not found. Please use \"mlr help list-flag-sections\" for a list.\n", - sectionName) +func showHelpForSection(sectionNames []string) { + for _, sectionName := range sectionNames { + if !cli.FLAG_TABLE.ShowHelpForSection(sectionName) { + fmt.Printf( + "mlr: flag-section \"%s\" not found. Please use \"mlr help list-flag-sections\" for a list.\n", + sectionName) + } } } // For on-the-fly `mlr help foo-bar-flags` where `Foo-bar flags` is the name of // a section in the FLAG_TABLE. See the func-init block at the top of this // file. -func showHelpForSectionViaDowndash(downdashSectionName string) { - if !cli.FLAG_TABLE.ShowHelpForSectionViaDowndash(downdashSectionName) { - fmt.Printf("mlr: flag-section \"%s\" not found.\n", downdashSectionName) +func showHelpForSectionViaDowndash(downdashSectionNames []string) { + for _, downdashSectionName := range downdashSectionNames { + if !cli.FLAG_TABLE.ShowHelpForSectionViaDowndash(downdashSectionName) { + fmt.Printf("mlr: flag-section \"%s\" not found.\n", downdashSectionName) + } } } // For webdocs autogen: we want the headline separately so we can backtick it. -func showHeadlineForFlag(flagName string) { - if !cli.FLAG_TABLE.ShowHeadlineForFlag(flagName) { - fmt.Printf("mlr: flag \"%s\" not found..\n", flagName) +func showHeadlineForFlag(flagNames []string) { + for _, flagName := range flagNames { + if !cli.FLAG_TABLE.ShowHeadlineForFlag(flagName) { + fmt.Printf("mlr: flag \"%s\" not found..\n", flagName) + } } } // For webdocs autogen -func showHelpForFlag(flagName string) { - if !cli.FLAG_TABLE.ShowHelpForFlag(flagName) { - fmt.Printf("mlr: flag \"%s\" not found..\n", flagName) +func showHelpForFlag(flagNames []string) { + for _, flagName := range flagNames { + if !cli.FLAG_TABLE.ShowHelpForFlag(flagName) { + fmt.Printf("mlr: flag \"%s\" not found..\n", flagName) + } } } @@ -543,14 +564,13 @@ func listVerbsAsParagraph() { transformers.ListVerbNamesAsParagraph() } -func helpForVerb(arg string) { - transformerSetup := transformers.LookUp(arg) - if transformerSetup != nil { - transformerSetup.UsageFunc(os.Stdout, true, 0) - } else { - fmt.Printf( - "mlr: verb \"%s\" not found. Please use \"mlr help list-verbs\" for a list.\n", - arg) +func helpForVerb(args []string) { + for _, arg := range args { + if !transformers.ShowHelpForTransformer(arg) { + fmt.Printf( + "mlr: verb \"%s\" not found. Please use \"mlr help list-verbs\" for a list.\n", + arg) + } } } @@ -571,8 +591,10 @@ func listFunctionClasses() { cst.BuiltinFunctionManagerInstance.ListBuiltinFunctionClasses() } -func listFunctionsInClass(class string) { - cst.BuiltinFunctionManagerInstance.ListBuiltinFunctionsInClass(class) +func listFunctionsInClass(classes []string) { + for _, class := range classes { + cst.BuiltinFunctionManagerInstance.ListBuiltinFunctionsInClass(class) + } } func listFunctionsAsParagraph() { @@ -591,45 +613,92 @@ func usageFunctionsByClass() { cst.BuiltinFunctionManagerInstance.ListBuiltinFunctionUsagesByClass() } -func helpForFunction(arg string) { - cst.BuiltinFunctionManagerInstance.TryListBuiltinFunctionUsage(arg, true) +func helpForFunction(args []string) { + for _, arg := range args { + cst.BuiltinFunctionManagerInstance.TryListBuiltinFunctionUsage(arg) + } } -// TODO: comment -// xxx polymorphic looker-upper: try: -// o flag -// o verb -// o function -// o keyword -// xxx note 'mlr help sort' finds verb before DSL function w/ same name ... -// xxx 'mlr help verb sort' vs 'mlr help function sort' -func helpBySearch(thing string) bool { +func helpByExactSearch(things []string) bool { + foundAny := false + for _, thing := range things { + foundThisOne := helpByExactSearchOne(thing) + foundAny = foundAny || foundThisOne + if !foundThisOne { + fmt.Printf("No help found for \"%s\". Please try 'mlr help find %s' for approximate match.\n", thing, thing) + fmt.Printf("See also 'mlr help topics'.\n") + } + } + + return foundAny +} + +// We need to look various places, e.g. "sec2gmt" is the name of a verb as well +// as a DSL function. +func helpByExactSearchOne(thing string) bool { + found := false // flag - if cli.FLAG_TABLE.ShowHelpForFlag(thing) { - return true + if cli.FLAG_TABLE.ShowHelpForFlagWithName(thing) { + found = true } // verb - transformerSetup := transformers.LookUp(thing) - if transformerSetup != nil { - transformerSetup.UsageFunc(os.Stdout, true, 0) - return true + if transformers.ShowHelpForTransformer(thing) { + found = true } // function - // to do: parameterize inexact-match printing ... - if cst.BuiltinFunctionManagerInstance.TryListBuiltinFunctionUsage(thing, false) { - return true + if cst.BuiltinFunctionManagerInstance.TryListBuiltinFunctionUsage(thing) { + found = true } // keyword if cst.TryUsageForKeyword(thing) { - return true + found = true } - // not found - return false + return found +} + +func helpByApproximateSearch(things []string) bool { + foundAny := false + for _, thing := range things { + foundThisOne := helpByApproximateSearchOne(thing) + foundAny = foundAny || foundThisOne + } + + return foundAny +} + +func helpByApproximateSearchOne(thing string) bool { + found := false + + // flag + if cli.FLAG_TABLE.ShowHelpForFlagApproximateWithName(thing) { + found = true + } + + // verb + if transformers.ShowHelpForTransformerApproximate(thing) { + found = true + } + + // function + if cst.BuiltinFunctionManagerInstance.TryListBuiltinFunctionUsageApproximate(thing) { + found = true + } + + // keyword + if cst.TryUsageForKeywordApproximate(thing) { + found = true + } + + if !found { + fmt.Printf("No help found for \"%s\". Please try 'mlr help find %s' for approximate match.\n", thing, thing) + fmt.Printf("See also 'mlr help topics'.\n") + } + return found } // ---------------------------------------------------------------- @@ -649,8 +718,10 @@ func usageKeywords() { cst.UsageKeywords() } -func helpForKeyword(arg string) { - cst.UsageForKeyword(arg) +func helpForKeyword(args []string) { + for _, arg := range args { + cst.UsageForKeyword(arg) + } } // ---------------------------------------------------------------- diff --git a/internal/pkg/auxents/regtest/entry.go b/internal/pkg/auxents/regtest/entry.go index 6c509a005..74d5ce0e3 100644 --- a/internal/pkg/auxents/regtest/entry.go +++ b/internal/pkg/auxents/regtest/entry.go @@ -12,11 +12,13 @@ import ( "strings" ) +const defaultPath = "./test/cases" + // ================================================================ func regTestUsage(verbName string, o *os.File, exitCode int) { exeName := path.Base(os.Args[0]) fmt.Fprintf(o, "Usage: %s %s [options] [one or more directories/files]\n", exeName, verbName) - fmt.Fprintf(o, "If no directories/files are specified, the directory %s is used by default.\n", DefaultPath) + fmt.Fprintf(o, "If no directories/files are specified, the directory %s is used by default.\n", defaultPath) fmt.Fprintf(o, "Recursively walks the directory/ies looking for foo.cmd files having Miller command-lines,\n") fmt.Fprintf(o, "with foo.expout and foo.experr files having expected stdout and stderr, respectively.\n") fmt.Fprintf(o, "If foo.should-fail exists and is a file, the command is expected to exit non-zero back to\n") @@ -94,6 +96,9 @@ func RegTestMain(args []string) int { } } casePaths := args[argi:] + if len(casePaths) == 0 { + casePaths = []string{defaultPath} + } regtester := NewRegTester( exeName, diff --git a/internal/pkg/auxents/regtest/regtester.go b/internal/pkg/auxents/regtest/regtester.go index 73e2dbf1a..31cd1c150 100644 --- a/internal/pkg/auxents/regtest/regtester.go +++ b/internal/pkg/auxents/regtest/regtester.go @@ -69,7 +69,6 @@ import ( "github.com/johnkerl/miller/internal/pkg/lib" ) -const DefaultPath = "./cases" const CmdName = "cmd" const MlrName = "mlr" const EnvName = "env" @@ -163,9 +162,7 @@ func (regtester *RegTester) Execute( regtester.resetCounts() - if len(casePaths) == 0 { - casePaths = []string{DefaultPath} - } + lib.InternalCodingErrorIf(len(casePaths) == 0) if !regtester.plainMode { fmt.Println("REGRESSION TEST:") diff --git a/internal/pkg/auxents/repl/verbs.go b/internal/pkg/auxents/repl/verbs.go index a941846f3..e36ac24ac 100644 --- a/internal/pkg/auxents/repl/verbs.go +++ b/internal/pkg/auxents/repl/verbs.go @@ -70,6 +70,31 @@ func (repl *Repl) findHandler(verbName string) *handlerInfo { return nil } +func (repl *Repl) showUsageForHandler(verbName string) bool { + nonDSLHandler := repl.findHandler(verbName) + if nonDSLHandler != nil { + fmt.Println(colorizer.MaybeColorizeHelp(verbName, true)) + nonDSLHandler.usageFunc(repl) + return true + } else { + return false + } +} + +func (repl *Repl) showUsageForHandlerApproximate(searchString string) bool { + foundAny := false + for _, entry := range handlerLookupTable { + for _, entryVerbName := range entry.verbNames { + if strings.Contains(entryVerbName, searchString) { + fmt.Println(colorizer.MaybeColorizeHelp(entryVerbName, true)) + entry.usageFunc(repl) + foundAny = true + } + } + } + return foundAny +} + // ---------------------------------------------------------------- // Handles a single non-DSL statement like ':open foo.dat' or ':help'. func (repl *Repl) handleNonDSLLine(trimmedLine string) bool { @@ -786,7 +811,7 @@ func usageHelp(repl *Repl) { fmt.Println(":help prompt") fmt.Println(":help function-names") fmt.Println(":help function-details") - fmt.Println(":help {function name}, e.g. :help sec2gmt") + fmt.Println(":help find {substring}, e.g. :help find gmt or :help find map") fmt.Println(":help {function name}, e.g. :help sec2gmt") } @@ -797,6 +822,14 @@ func handleHelp(repl *Repl, args []string) bool { return true } + if len(args) >= 1 && args[0] == "find" { + args = args[1:] + for _, arg := range args { + handleHelpFindSingle(repl, arg) + } + return true + } + for _, arg := range args { handleHelpSingle(repl, arg) } @@ -804,6 +837,26 @@ func handleHelp(repl *Repl, args []string) bool { return true } +func handleHelpFindSingle(repl *Repl, arg string) { + foundAny := false + + if cst.TryUsageForKeywordApproximate(arg) { + foundAny = true + } + + if cst.BuiltinFunctionManagerInstance.TryListBuiltinFunctionUsageApproximate(arg) { + foundAny = true + } + + if repl.showUsageForHandlerApproximate(arg) { + foundAny = true + } + + if !foundAny { + fmt.Printf("No help available for %s. Try \":help find %s\" to search for matches\n", arg, arg) + } +} + func handleHelpSingle(repl *Repl, arg string) { if arg == "intro" { showREPLIntro(repl) @@ -872,13 +925,11 @@ func handleHelpSingle(repl *Repl, arg string) { return } - if cst.BuiltinFunctionManagerInstance.TryListBuiltinFunctionUsage(arg, true) { + if cst.BuiltinFunctionManagerInstance.TryListBuiltinFunctionUsage(arg) { return } - nonDSLHandler := repl.findHandler(arg) - if nonDSLHandler != nil { - nonDSLHandler.usageFunc(repl) + if repl.showUsageForHandler(arg) { return } diff --git a/internal/pkg/cli/flag_types.go b/internal/pkg/cli/flag_types.go index caeea95c6..4a285962c 100644 --- a/internal/pkg/cli/flag_types.go +++ b/internal/pkg/cli/flag_types.go @@ -258,9 +258,25 @@ func (ft *FlagTable) ShowHeadlineForFlag(flagName string) bool { // webdoc usage where the browser does dynamic line-wrapping, as the user // resizes the browser window. func (ft *FlagTable) ShowHelpForFlag(flagName string) bool { + return ft.showHelpForFlagMaybeWithName(flagName, false) +} + +// ShowHelpForFlagWithName prints the flag's name colorized, then flag's +// help-string all on one line. This is for on-line help usage. +func (ft *FlagTable) ShowHelpForFlagWithName(flagName string) bool { + return ft.showHelpForFlagMaybeWithName(flagName, true) +} + +// showHelpForFlagMaybeWithName supports ShowHelpForFlag and ShowHelpForFlagWithName. +// webdoc usage where the browser does dynamic line-wrapping, as the user +// resizes the browser window. +func (ft *FlagTable) showHelpForFlagMaybeWithName(flagName string, showName bool) bool { for _, fs := range ft.sections { for _, flag := range fs.flags { if flag.Owns(flagName) { + if showName { + fmt.Println(colorizer.MaybeColorizeHelp(flagName, true)) + } fmt.Println(flag.GetHelpOneLine()) return true } @@ -269,6 +285,20 @@ func (ft *FlagTable) ShowHelpForFlag(flagName string) bool { return false } +// ShowHelpForFlagApproximateWithName is like ShowHelpForFlagWithName +// but allows substring matches. This is for on-line help usage. +func (ft *FlagTable) ShowHelpForFlagApproximateWithName(searchString string) bool { + for _, fs := range ft.sections { + for _, flag := range fs.flags { + if flag.Matches(searchString) { + fmt.Println(colorizer.MaybeColorizeHelp(flag.name, true)) + fmt.Println(flag.GetHelpOneLine()) + } + } + } + return false +} + // Map "CSV-only flags" to "csv-only-flags" etc. for the benefit of per-section // help in `mlr help topics`. func (ft *FlagTable) GetDowndashSectionNames() []string { @@ -361,14 +391,32 @@ func (fs *FlagSection) NilCheck() { // ================================================================ // Flag methods -// Owns determines whether this object handles a command-line flag such as "--foo". +// Owns determines whether this object handles a command-line flag such as +// "--foo". This is used for command-line parsing, as well as for on-line help +// with exact match on flag name. func (flag *Flag) Owns(input string) bool { - if input == flag.name { + if flag.name == input { return true } if flag.altNames != nil { for _, name := range flag.altNames { - if input == name { + if name == input { + return true + } + } + } + return false +} + +// Matches is like Owns but is for substring matching, for on-line help with +// approximate match on flag name. +func (flag *Flag) Matches(input string) bool { + if strings.Contains(flag.name, input) { + return true + } + if flag.altNames != nil { + for _, name := range flag.altNames { + if strings.Contains(name, input) { return true } } diff --git a/internal/pkg/dsl/cst/builtin_function_manager.go b/internal/pkg/dsl/cst/builtin_function_manager.go index cf42a7e84..d90eec326 100644 --- a/internal/pkg/dsl/cst/builtin_function_manager.go +++ b/internal/pkg/dsl/cst/builtin_function_manager.go @@ -1906,27 +1906,35 @@ func (manager *BuiltinFunctionManager) ListBuiltinFunctionUsagesByClass() { } func (manager *BuiltinFunctionManager) ListBuiltinFunctionUsage(functionName string) { - // xxx remove bool-arg code smell - if !manager.TryListBuiltinFunctionUsage(functionName, true) { + if !manager.TryListBuiltinFunctionUsage(functionName) { fmt.Fprintf(os.Stderr, "Function \"%s\" not found.\n", functionName) } } func (manager *BuiltinFunctionManager) TryListBuiltinFunctionUsage( functionName string, - showApproximate bool, ) bool { builtinFunctionInfo := manager.LookUp(functionName) if builtinFunctionInfo == nil { - if showApproximate { - manager.listBuiltinFunctionUsageApproximate(functionName) - } return false } manager.listBuiltinFunctionUsageExact(builtinFunctionInfo) return true } +func (manager *BuiltinFunctionManager) TryListBuiltinFunctionUsageApproximate( + searchString string, +) bool { + found := false + for _, builtinFunctionInfo := range *manager.lookupTable { + if strings.Contains(builtinFunctionInfo.name, searchString) { + manager.showSingleUsage(&builtinFunctionInfo) + found = true + } + } + return found +} + func (manager *BuiltinFunctionManager) listBuiltinFunctionUsageExact( builtinFunctionInfo *BuiltinFunctionInfo, ) { @@ -1955,10 +1963,9 @@ func (manager *BuiltinFunctionManager) showSingleUsage( } } -func (manager *BuiltinFunctionManager) listBuiltinFunctionUsageApproximate( +func (manager *BuiltinFunctionManager) ListBuiltinFunctionUsageApproximate( text string, -) { - fmt.Printf("No exact match for \"%s\". Inexact matches:\n", text) +) bool { found := false for _, builtinFunctionInfo := range *manager.lookupTable { if strings.Contains(builtinFunctionInfo.name, text) { @@ -1966,9 +1973,7 @@ func (manager *BuiltinFunctionManager) listBuiltinFunctionUsageApproximate( found = true } } - if !found { - fmt.Println("None found.") - } + return found } func describeNargs(info *BuiltinFunctionInfo) string { diff --git a/internal/pkg/dsl/cst/keyword_usage.go b/internal/pkg/dsl/cst/keyword_usage.go index 807c8527d..0972cbce8 100644 --- a/internal/pkg/dsl/cst/keyword_usage.go +++ b/internal/pkg/dsl/cst/keyword_usage.go @@ -2,6 +2,7 @@ package cst import ( "fmt" + "strings" "github.com/johnkerl/miller/internal/pkg/colorizer" "github.com/johnkerl/miller/internal/pkg/lib" @@ -102,6 +103,18 @@ func TryUsageForKeyword(name string) bool { return false } +func TryUsageForKeywordApproximate(searchString string) bool { + foundAny := false + for _, entry := range KEYWORD_USAGE_TABLE { + if strings.Contains(entry.name, searchString) { + fmt.Printf("%s: ", colorizer.MaybeColorizeHelp(entry.name, true)) + entry.usageFunc() + foundAny = true + } + } + return foundAny +} + // ---------------------------------------------------------------- func ListKeywordsVertically() { for _, entry := range KEYWORD_USAGE_TABLE { diff --git a/internal/pkg/transformers/aaa_transformer_table.go b/internal/pkg/transformers/aaa_transformer_table.go index 3c2a0acaf..ed6c0a84d 100644 --- a/internal/pkg/transformers/aaa_transformer_table.go +++ b/internal/pkg/transformers/aaa_transformer_table.go @@ -3,6 +3,7 @@ package transformers import ( "fmt" "os" + "strings" "github.com/johnkerl/miller/internal/pkg/colorizer" "github.com/johnkerl/miller/internal/pkg/lib" @@ -71,7 +72,28 @@ var TRANSFORMER_LOOKUP_TABLE = []TransformerSetup{ UnsparsifySetup, } -// ---------------------------------------------------------------- +func ShowHelpForTransformer(verb string) bool { + transformerSetup := LookUp(verb) + if transformerSetup != nil { + fmt.Println(colorizer.MaybeColorizeHelp(transformerSetup.Verb, true)) + transformerSetup.UsageFunc(os.Stdout, false, 0) + return true + } + return false +} + +func ShowHelpForTransformerApproximate(searchString string) bool { + found := false + for _, transformerSetup := range TRANSFORMER_LOOKUP_TABLE { + if strings.Contains(transformerSetup.Verb, searchString) { + fmt.Println(colorizer.MaybeColorizeHelp(transformerSetup.Verb, true)) + transformerSetup.UsageFunc(os.Stdout, false, 0) + found = true + } + } + return found +} + func LookUp(verb string) *TransformerSetup { for _, transformerSetup := range TRANSFORMER_LOOKUP_TABLE { if transformerSetup.Verb == verb { @@ -81,14 +103,12 @@ func LookUp(verb string) *TransformerSetup { return nil } -// ---------------------------------------------------------------- func ListVerbNamesVertically() { for _, transformerSetup := range TRANSFORMER_LOOKUP_TABLE { fmt.Printf("%s\n", transformerSetup.Verb) } } -// ---------------------------------------------------------------- func ListVerbNamesAsParagraph() { verbNames := make([]string, len(TRANSFORMER_LOOKUP_TABLE)) diff --git a/man/manpage.txt b/man/manpage.txt index 56201690b..08db5cd67 100644 --- a/man/manpage.txt +++ b/man/manpage.txt @@ -151,11 +151,10 @@ HELP OPTIONS mlr -F = mlr help usage-functions mlr -k = mlr help list-keywords mlr -K = mlr help usage-keywords - Lastly, 'mlr help ...' will search for your text '...' using the sources of + Lastly, 'mlr help ...' will search for your exact text '...' using the sources of 'mlr help flag', 'mlr help verb', 'mlr help function', and 'mlr help keyword'. - For things appearing in more than one place, e.g. 'sec2gmt' which is the name of a - verb as well as a function, use `mlr help verb sec2gmt' or `mlr help function sec2gmt' - to disambiguate. + Use 'mlr help find ...' for approximate (substring) matches, e.g. 'mlr help find map' + for all things with "map" in their names. VERB LIST altkv bar bootstrap cat check clean-whitespace count-distinct count @@ -2959,4 +2958,4 @@ SEE ALSO - 2021-11-15 MILLER(1) + 2021-11-18 MILLER(1) diff --git a/man/mlr.1 b/man/mlr.1 index ca61710c5..315f86366 100644 --- a/man/mlr.1 +++ b/man/mlr.1 @@ -2,12 +2,12 @@ .\" Title: mlr .\" Author: [see the "AUTHOR" section] .\" Generator: ./mkman.rb -.\" Date: 2021-11-15 +.\" Date: 2021-11-18 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MILLER" "1" "2021-11-15" "\ \&" "\ \&" +.TH "MILLER" "1" "2021-11-18" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Portability definitions .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -186,11 +186,10 @@ Shorthands: mlr -F = mlr help usage-functions mlr -k = mlr help list-keywords mlr -K = mlr help usage-keywords -Lastly, 'mlr help ...' will search for your text '...' using the sources of +Lastly, 'mlr help ...' will search for your exact text '...' using the sources of \(cqmlr help flag', 'mlr help verb', 'mlr help function', and 'mlr help keyword'. -For things appearing in more than one place, e.g. 'sec2gmt' which is the name of a -verb as well as a function, use `mlr help verb sec2gmt' or `mlr help function sec2gmt' -to disambiguate. +Use 'mlr help find ...' for approximate (substring) matches, e.g. 'mlr help find map' +for all things with "map" in their names. .fi .if n \{\ .RE diff --git a/test/cases/help/0001/cmd b/test/cases/help/0001/cmd new file mode 100644 index 000000000..4c30096cb --- /dev/null +++ b/test/cases/help/0001/cmd @@ -0,0 +1 @@ +mlr help cos diff --git a/test/cases/help/0001/experr b/test/cases/help/0001/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0001/expout b/test/cases/help/0001/expout new file mode 100644 index 000000000..59ee1e4fb --- /dev/null +++ b/test/cases/help/0001/expout @@ -0,0 +1 @@ +cos (class=math #args=1) Trigonometric cosine. diff --git a/test/cases/help/0002/cmd b/test/cases/help/0002/cmd new file mode 100644 index 000000000..02371dc8f --- /dev/null +++ b/test/cases/help/0002/cmd @@ -0,0 +1 @@ +mlr help cos sin diff --git a/test/cases/help/0002/experr b/test/cases/help/0002/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0002/expout b/test/cases/help/0002/expout new file mode 100644 index 000000000..1529b7199 --- /dev/null +++ b/test/cases/help/0002/expout @@ -0,0 +1,2 @@ +cos (class=math #args=1) Trigonometric cosine. +sin (class=math #args=1) Trigonometric sine. diff --git a/test/cases/help/0003/cmd b/test/cases/help/0003/cmd new file mode 100644 index 000000000..938fd5ac4 --- /dev/null +++ b/test/cases/help/0003/cmd @@ -0,0 +1 @@ +mlr help nonesuch diff --git a/test/cases/help/0003/experr b/test/cases/help/0003/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0003/expout b/test/cases/help/0003/expout new file mode 100644 index 000000000..b39493a58 --- /dev/null +++ b/test/cases/help/0003/expout @@ -0,0 +1,2 @@ +No help found for "nonesuch". Please try 'mlr help find nonesuch' for approximate match. +See also 'mlr help topics'. diff --git a/test/cases/help/0004/cmd b/test/cases/help/0004/cmd new file mode 100644 index 000000000..8f4d5fef8 --- /dev/null +++ b/test/cases/help/0004/cmd @@ -0,0 +1 @@ +mlr help nonesuch sin diff --git a/test/cases/help/0004/experr b/test/cases/help/0004/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0004/expout b/test/cases/help/0004/expout new file mode 100644 index 000000000..2957a47dd --- /dev/null +++ b/test/cases/help/0004/expout @@ -0,0 +1,3 @@ +No help found for "nonesuch". Please try 'mlr help find nonesuch' for approximate match. +See also 'mlr help topics'. +sin (class=math #args=1) Trigonometric sine. diff --git a/test/cases/help/0005/cmd b/test/cases/help/0005/cmd new file mode 100644 index 000000000..5dacd53eb --- /dev/null +++ b/test/cases/help/0005/cmd @@ -0,0 +1 @@ +mlr help cos nonesuch diff --git a/test/cases/help/0005/experr b/test/cases/help/0005/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0005/expout b/test/cases/help/0005/expout new file mode 100644 index 000000000..706bbda4c --- /dev/null +++ b/test/cases/help/0005/expout @@ -0,0 +1,3 @@ +cos (class=math #args=1) Trigonometric cosine. +No help found for "nonesuch". Please try 'mlr help find nonesuch' for approximate match. +See also 'mlr help topics'. diff --git a/test/cases/help/0006/cmd b/test/cases/help/0006/cmd new file mode 100644 index 000000000..5ab70547a --- /dev/null +++ b/test/cases/help/0006/cmd @@ -0,0 +1 @@ +mlr help find cos diff --git a/test/cases/help/0006/experr b/test/cases/help/0006/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0006/expout b/test/cases/help/0006/expout new file mode 100644 index 000000000..7e39509e9 --- /dev/null +++ b/test/cases/help/0006/expout @@ -0,0 +1,4 @@ +acos (class=math #args=1) Inverse trigonometric cosine. +acosh (class=math #args=1) Inverse hyperbolic cosine. +cos (class=math #args=1) Trigonometric cosine. +cosh (class=math #args=1) Hyperbolic cosine. diff --git a/test/cases/help/0007/cmd b/test/cases/help/0007/cmd new file mode 100644 index 000000000..9f8308c45 --- /dev/null +++ b/test/cases/help/0007/cmd @@ -0,0 +1 @@ +mlr help find cos sin diff --git a/test/cases/help/0007/experr b/test/cases/help/0007/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0007/expout b/test/cases/help/0007/expout new file mode 100644 index 000000000..c6c0b22c8 --- /dev/null +++ b/test/cases/help/0007/expout @@ -0,0 +1,8 @@ +acos (class=math #args=1) Inverse trigonometric cosine. +acosh (class=math #args=1) Inverse hyperbolic cosine. +cos (class=math #args=1) Trigonometric cosine. +cosh (class=math #args=1) Hyperbolic cosine. +asin (class=math #args=1) Inverse trigonometric sine. +asinh (class=math #args=1) Inverse hyperbolic sine. +sin (class=math #args=1) Trigonometric sine. +sinh (class=math #args=1) Hyperbolic sine. diff --git a/test/cases/help/0008/cmd b/test/cases/help/0008/cmd new file mode 100644 index 000000000..21289ba04 --- /dev/null +++ b/test/cases/help/0008/cmd @@ -0,0 +1 @@ +mlr help find nonesuch diff --git a/test/cases/help/0008/experr b/test/cases/help/0008/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0008/expout b/test/cases/help/0008/expout new file mode 100644 index 000000000..b39493a58 --- /dev/null +++ b/test/cases/help/0008/expout @@ -0,0 +1,2 @@ +No help found for "nonesuch". Please try 'mlr help find nonesuch' for approximate match. +See also 'mlr help topics'. diff --git a/test/cases/help/0009/cmd b/test/cases/help/0009/cmd new file mode 100644 index 000000000..fd26d1f11 --- /dev/null +++ b/test/cases/help/0009/cmd @@ -0,0 +1 @@ +mlr help find nonesuch sin diff --git a/test/cases/help/0009/experr b/test/cases/help/0009/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0009/expout b/test/cases/help/0009/expout new file mode 100644 index 000000000..1e09eb9ec --- /dev/null +++ b/test/cases/help/0009/expout @@ -0,0 +1,6 @@ +No help found for "nonesuch". Please try 'mlr help find nonesuch' for approximate match. +See also 'mlr help topics'. +asin (class=math #args=1) Inverse trigonometric sine. +asinh (class=math #args=1) Inverse hyperbolic sine. +sin (class=math #args=1) Trigonometric sine. +sinh (class=math #args=1) Hyperbolic sine. diff --git a/test/cases/help/0010/cmd b/test/cases/help/0010/cmd new file mode 100644 index 000000000..5dacd53eb --- /dev/null +++ b/test/cases/help/0010/cmd @@ -0,0 +1 @@ +mlr help cos nonesuch diff --git a/test/cases/help/0010/experr b/test/cases/help/0010/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0010/expout b/test/cases/help/0010/expout new file mode 100644 index 000000000..706bbda4c --- /dev/null +++ b/test/cases/help/0010/expout @@ -0,0 +1,3 @@ +cos (class=math #args=1) Trigonometric cosine. +No help found for "nonesuch". Please try 'mlr help find nonesuch' for approximate match. +See also 'mlr help topics'. diff --git a/test/cases/help/0011/cmd b/test/cases/help/0011/cmd new file mode 100644 index 000000000..79e4e3cdc --- /dev/null +++ b/test/cases/help/0011/cmd @@ -0,0 +1 @@ +mlr help for diff --git a/test/cases/help/0011/experr b/test/cases/help/0011/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0011/expout b/test/cases/help/0011/expout new file mode 100644 index 000000000..9f5c6b71f --- /dev/null +++ b/test/cases/help/0011/expout @@ -0,0 +1,15 @@ +for: defines a for-loop using one of three styles. The body statements must +be wrapped in curly braces. +For-loop over stream record: + + Example: 'for (k, v in $*) { ... }' + +For-loop over out-of-stream variables: + + Example: 'for (k, v in @counts) { ... }' + Example: 'for ((k1, k2), v in @counts) { ... }' + Example: 'for ((k1, k2, k3), v in @*) { ... }' + +C-style for-loop: + + Example: 'for (var i = 0, var b = 1; i < 10; i += 1, b *= 2) { ... }' diff --git a/test/cases/help/0012/cmd b/test/cases/help/0012/cmd new file mode 100644 index 000000000..814997851 --- /dev/null +++ b/test/cases/help/0012/cmd @@ -0,0 +1 @@ +mlr help find for diff --git a/test/cases/help/0012/experr b/test/cases/help/0012/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0012/expout b/test/cases/help/0012/expout new file mode 100644 index 000000000..245e2ab33 --- /dev/null +++ b/test/cases/help/0012/expout @@ -0,0 +1,45 @@ +format-values +Usage: mlr format-values [options] +Applies format strings to all field values, depending on autodetected type. +* If a field value is detected to be integer, applies integer format. +* Else, if a field value is detected to be float, applies float format. +* Else, applies string format. + +Note: this is a low-keystroke way to apply formatting to many fields. To get +finer control, please see the fmtnum function within the mlr put DSL. + +Note: this verb lets you apply arbitrary format strings, which can produce +undefined behavior and/or program crashes. See your system's "man printf". + +Options: +-i {integer format} Defaults to "%d". + Examples: "%06lld", "%08llx". + Note that Miller integers are long long so you must use + formats which apply to long long, e.g. with ll in them. + Undefined behavior results otherwise. +-f {float format} Defaults to "%f". + Examples: "%8.3lf", "%.6le". + Note that Miller floats are double-precision so you must + use formats which apply to double, e.g. with l[efg] in them. + Undefined behavior results otherwise. +-s {string format} Defaults to "%s". + Examples: "_%s", "%08s". + Note that you must use formats which apply to string, e.g. + with s in them. Undefined behavior results otherwise. +-n Coerce field values autodetected as int to float, and then + apply the float format. +for: defines a for-loop using one of three styles. The body statements must +be wrapped in curly braces. +For-loop over stream record: + + Example: 'for (k, v in $*) { ... }' + +For-loop over out-of-stream variables: + + Example: 'for (k, v in @counts) { ... }' + Example: 'for ((k1, k2), v in @counts) { ... }' + Example: 'for ((k1, k2, k3), v in @*) { ... }' + +C-style for-loop: + + Example: 'for (var i = 0, var b = 1; i < 10; i += 1, b *= 2) { ... }' diff --git a/test/cases/help/0013/cmd b/test/cases/help/0013/cmd new file mode 100644 index 000000000..b3cc86b0b --- /dev/null +++ b/test/cases/help/0013/cmd @@ -0,0 +1 @@ +mlr help sec2 diff --git a/test/cases/help/0013/experr b/test/cases/help/0013/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0013/expout b/test/cases/help/0013/expout new file mode 100644 index 000000000..39d075259 --- /dev/null +++ b/test/cases/help/0013/expout @@ -0,0 +1,2 @@ +No help found for "sec2". Please try 'mlr help find sec2' for approximate match. +See also 'mlr help topics'. diff --git a/test/cases/help/0014/cmd b/test/cases/help/0014/cmd new file mode 100644 index 000000000..990a00af1 --- /dev/null +++ b/test/cases/help/0014/cmd @@ -0,0 +1 @@ +mlr help find sec2 diff --git a/test/cases/help/0014/experr b/test/cases/help/0014/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0014/expout b/test/cases/help/0014/expout new file mode 100644 index 000000000..97977a3db --- /dev/null +++ b/test/cases/help/0014/expout @@ -0,0 +1,44 @@ +sec2gmtdate +Usage: ../c/mlr sec2gmtdate {comma-separated list of field names} +Replaces a numeric field representing seconds since the epoch with the +corresponding GMT year-month-day timestamp; leaves non-numbers as-is. +This is nothing more than a keystroke-saver for the sec2gmtdate function: + ../c/mlr sec2gmtdate time1,time2 +is the same as + ../c/mlr put '$time1=sec2gmtdate($time1);$time2=sec2gmtdate($time2)' +sec2gmt +Usage: mlr sec2gmt [options] {comma-separated list of field names} +Replaces a numeric field representing seconds since the epoch with the +corresponding GMT timestamp; leaves non-numbers as-is. This is nothing +more than a keystroke-saver for the sec2gmt function: + mlr sec2gmt time1,time2 +is the same as + mlr put '$time1 = sec2gmt($time1); $time2 = sec2gmt($time2)' +Options: +-1 through -9: format the seconds using 1..9 decimal places, respectively. +--millis Input numbers are treated as milliseconds since the epoch. +--micros Input numbers are treated as microseconds since the epoch. +--nanos Input numbers are treated as nanoseconds since the epoch. +-h|--help Show this message. +fsec2dhms (class=time #args=1) Formats floating-point seconds as in fsec2dhms(500000.25) = "5d18h53m20.250000s" +fsec2hms (class=time #args=1) Formats floating-point seconds as in fsec2hms(5000.25) = "01:23:20.250000" +sec2dhms (class=time #args=1) Formats integer seconds as in sec2dhms(500000) = "5d18h53m20s" +sec2gmt (class=time #args=1,2) Formats seconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part. +Examples: +sec2gmt(1234567890) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456, 6) = "2009-02-13T23:31:30.123456Z" +sec2gmtdate (class=time #args=1) Formats seconds since epoch (integer part) as GMT timestamp with year-month-date. Leaves non-numbers as-is. +Example: +sec2gmtdate(1440768801.7) = "2015-08-28". +sec2hms (class=time #args=1) Formats integer seconds as in sec2hms(5000) = "01:23:20" +sec2localdate (class=time #args=1,2) Formats seconds since epoch (integer part) as local timestamp with year-month-date. Leaves non-numbers as-is. Consults $TZ environment variable unless second argument is supplied. +Examples: +sec2localdate(1440768801.7) = "2015-08-28" with TZ="Asia/Istanbul" +sec2localdate(1440768801.7, "Asia/Istanbul") = "2015-08-28" +sec2localtime (class=time #args=1,2,3) Formats seconds since epoch (integer part) as local timestamp. Consults $TZ environment variable unless third argument is supplied. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part +Examples: +sec2localtime(1234567890) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul" +sec2localtime(1234567890.123456) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul" +sec2localtime(1234567890.123456, 6) = "2009-02-14 01:31:30.123456" with TZ="Asia/Istanbul" +sec2localtime(1234567890.123456, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.123456" diff --git a/test/cases/help/0015/cmd b/test/cases/help/0015/cmd new file mode 100644 index 000000000..dd88ca8b5 --- /dev/null +++ b/test/cases/help/0015/cmd @@ -0,0 +1 @@ +mlr help sec2gmt diff --git a/test/cases/help/0015/experr b/test/cases/help/0015/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0015/expout b/test/cases/help/0015/expout new file mode 100644 index 000000000..cf4bafab7 --- /dev/null +++ b/test/cases/help/0015/expout @@ -0,0 +1,19 @@ +sec2gmt +Usage: mlr sec2gmt [options] {comma-separated list of field names} +Replaces a numeric field representing seconds since the epoch with the +corresponding GMT timestamp; leaves non-numbers as-is. This is nothing +more than a keystroke-saver for the sec2gmt function: + mlr sec2gmt time1,time2 +is the same as + mlr put '$time1 = sec2gmt($time1); $time2 = sec2gmt($time2)' +Options: +-1 through -9: format the seconds using 1..9 decimal places, respectively. +--millis Input numbers are treated as milliseconds since the epoch. +--micros Input numbers are treated as microseconds since the epoch. +--nanos Input numbers are treated as nanoseconds since the epoch. +-h|--help Show this message. +sec2gmt (class=time #args=1,2) Formats seconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part. +Examples: +sec2gmt(1234567890) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456, 6) = "2009-02-13T23:31:30.123456Z" diff --git a/test/cases/help/0016/cmd b/test/cases/help/0016/cmd new file mode 100644 index 000000000..2fa6ad66c --- /dev/null +++ b/test/cases/help/0016/cmd @@ -0,0 +1 @@ +mlr help find sec2gmt diff --git a/test/cases/help/0016/experr b/test/cases/help/0016/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0016/expout b/test/cases/help/0016/expout new file mode 100644 index 000000000..87aa76721 --- /dev/null +++ b/test/cases/help/0016/expout @@ -0,0 +1,30 @@ +sec2gmtdate +Usage: ../c/mlr sec2gmtdate {comma-separated list of field names} +Replaces a numeric field representing seconds since the epoch with the +corresponding GMT year-month-day timestamp; leaves non-numbers as-is. +This is nothing more than a keystroke-saver for the sec2gmtdate function: + ../c/mlr sec2gmtdate time1,time2 +is the same as + ../c/mlr put '$time1=sec2gmtdate($time1);$time2=sec2gmtdate($time2)' +sec2gmt +Usage: mlr sec2gmt [options] {comma-separated list of field names} +Replaces a numeric field representing seconds since the epoch with the +corresponding GMT timestamp; leaves non-numbers as-is. This is nothing +more than a keystroke-saver for the sec2gmt function: + mlr sec2gmt time1,time2 +is the same as + mlr put '$time1 = sec2gmt($time1); $time2 = sec2gmt($time2)' +Options: +-1 through -9: format the seconds using 1..9 decimal places, respectively. +--millis Input numbers are treated as milliseconds since the epoch. +--micros Input numbers are treated as microseconds since the epoch. +--nanos Input numbers are treated as nanoseconds since the epoch. +-h|--help Show this message. +sec2gmt (class=time #args=1,2) Formats seconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part. +Examples: +sec2gmt(1234567890) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456, 6) = "2009-02-13T23:31:30.123456Z" +sec2gmtdate (class=time #args=1) Formats seconds since epoch (integer part) as GMT timestamp with year-month-date. Leaves non-numbers as-is. +Example: +sec2gmtdate(1440768801.7) = "2015-08-28". diff --git a/test/cases/help/0017/cmd b/test/cases/help/0017/cmd new file mode 100644 index 000000000..a525d1fb4 --- /dev/null +++ b/test/cases/help/0017/cmd @@ -0,0 +1 @@ +mlr help --csv diff --git a/test/cases/help/0017/experr b/test/cases/help/0017/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0017/expout b/test/cases/help/0017/expout new file mode 100644 index 000000000..9c3ab866f --- /dev/null +++ b/test/cases/help/0017/expout @@ -0,0 +1,2 @@ +--csv +Use CSV format for input and output data. diff --git a/test/cases/help/0018/cmd b/test/cases/help/0018/cmd new file mode 100644 index 000000000..0da8741c9 --- /dev/null +++ b/test/cases/help/0018/cmd @@ -0,0 +1 @@ +mlr help find --csv diff --git a/test/cases/help/0018/experr b/test/cases/help/0018/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/help/0018/expout b/test/cases/help/0018/expout new file mode 100644 index 000000000..560401525 --- /dev/null +++ b/test/cases/help/0018/expout @@ -0,0 +1,6 @@ +--csv +Use CSV format for input and output data. +--csvlite +Use CSV-lite format for input and output data. +No help found for "--csv". Please try 'mlr help find --csv' for approximate match. +See also 'mlr help topics'. diff --git a/test/cases/repl-help/0001/cmd b/test/cases/repl-help/0001/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0001/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0001/experr b/test/cases/repl-help/0001/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0001/expout b/test/cases/repl-help/0001/expout new file mode 100644 index 000000000..59ee1e4fb --- /dev/null +++ b/test/cases/repl-help/0001/expout @@ -0,0 +1 @@ +cos (class=math #args=1) Trigonometric cosine. diff --git a/test/cases/repl-help/0001/input b/test/cases/repl-help/0001/input new file mode 100644 index 000000000..11118bb2e --- /dev/null +++ b/test/cases/repl-help/0001/input @@ -0,0 +1 @@ +:help cos diff --git a/test/cases/repl-help/0002/cmd b/test/cases/repl-help/0002/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0002/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0002/experr b/test/cases/repl-help/0002/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0002/expout b/test/cases/repl-help/0002/expout new file mode 100644 index 000000000..1529b7199 --- /dev/null +++ b/test/cases/repl-help/0002/expout @@ -0,0 +1,2 @@ +cos (class=math #args=1) Trigonometric cosine. +sin (class=math #args=1) Trigonometric sine. diff --git a/test/cases/repl-help/0002/input b/test/cases/repl-help/0002/input new file mode 100644 index 000000000..fe91e6745 --- /dev/null +++ b/test/cases/repl-help/0002/input @@ -0,0 +1 @@ +:help cos sin diff --git a/test/cases/repl-help/0003/cmd b/test/cases/repl-help/0003/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0003/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0003/experr b/test/cases/repl-help/0003/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0003/expout b/test/cases/repl-help/0003/expout new file mode 100644 index 000000000..6c499ebae --- /dev/null +++ b/test/cases/repl-help/0003/expout @@ -0,0 +1 @@ +No help available for nonesuch diff --git a/test/cases/repl-help/0003/input b/test/cases/repl-help/0003/input new file mode 100644 index 000000000..07b3f318d --- /dev/null +++ b/test/cases/repl-help/0003/input @@ -0,0 +1 @@ +:help nonesuch diff --git a/test/cases/repl-help/0004/cmd b/test/cases/repl-help/0004/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0004/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0004/experr b/test/cases/repl-help/0004/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0004/expout b/test/cases/repl-help/0004/expout new file mode 100644 index 000000000..3519be25c --- /dev/null +++ b/test/cases/repl-help/0004/expout @@ -0,0 +1,2 @@ +No help available for nonesuch +sin (class=math #args=1) Trigonometric sine. diff --git a/test/cases/repl-help/0004/input b/test/cases/repl-help/0004/input new file mode 100644 index 000000000..7bd372580 --- /dev/null +++ b/test/cases/repl-help/0004/input @@ -0,0 +1 @@ +:help nonesuch sin diff --git a/test/cases/repl-help/0005/cmd b/test/cases/repl-help/0005/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0005/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0005/experr b/test/cases/repl-help/0005/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0005/expout b/test/cases/repl-help/0005/expout new file mode 100644 index 000000000..8369d3d44 --- /dev/null +++ b/test/cases/repl-help/0005/expout @@ -0,0 +1,2 @@ +cos (class=math #args=1) Trigonometric cosine. +No help available for nonesuch diff --git a/test/cases/repl-help/0005/input b/test/cases/repl-help/0005/input new file mode 100644 index 000000000..44f267d0b --- /dev/null +++ b/test/cases/repl-help/0005/input @@ -0,0 +1 @@ +:help cos nonesuch diff --git a/test/cases/repl-help/0006/cmd b/test/cases/repl-help/0006/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0006/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0006/experr b/test/cases/repl-help/0006/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0006/expout b/test/cases/repl-help/0006/expout new file mode 100644 index 000000000..7e39509e9 --- /dev/null +++ b/test/cases/repl-help/0006/expout @@ -0,0 +1,4 @@ +acos (class=math #args=1) Inverse trigonometric cosine. +acosh (class=math #args=1) Inverse hyperbolic cosine. +cos (class=math #args=1) Trigonometric cosine. +cosh (class=math #args=1) Hyperbolic cosine. diff --git a/test/cases/repl-help/0006/input b/test/cases/repl-help/0006/input new file mode 100644 index 000000000..40e82b097 --- /dev/null +++ b/test/cases/repl-help/0006/input @@ -0,0 +1 @@ +:help find cos diff --git a/test/cases/repl-help/0007/cmd b/test/cases/repl-help/0007/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0007/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0007/experr b/test/cases/repl-help/0007/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0007/expout b/test/cases/repl-help/0007/expout new file mode 100644 index 000000000..c6c0b22c8 --- /dev/null +++ b/test/cases/repl-help/0007/expout @@ -0,0 +1,8 @@ +acos (class=math #args=1) Inverse trigonometric cosine. +acosh (class=math #args=1) Inverse hyperbolic cosine. +cos (class=math #args=1) Trigonometric cosine. +cosh (class=math #args=1) Hyperbolic cosine. +asin (class=math #args=1) Inverse trigonometric sine. +asinh (class=math #args=1) Inverse hyperbolic sine. +sin (class=math #args=1) Trigonometric sine. +sinh (class=math #args=1) Hyperbolic sine. diff --git a/test/cases/repl-help/0007/input b/test/cases/repl-help/0007/input new file mode 100644 index 000000000..1bc0dae93 --- /dev/null +++ b/test/cases/repl-help/0007/input @@ -0,0 +1 @@ +:help find cos sin diff --git a/test/cases/repl-help/0008/cmd b/test/cases/repl-help/0008/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0008/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0008/experr b/test/cases/repl-help/0008/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0008/expout b/test/cases/repl-help/0008/expout new file mode 100644 index 000000000..61bce8170 --- /dev/null +++ b/test/cases/repl-help/0008/expout @@ -0,0 +1 @@ +No help available for nonesuch. Try ":help find nonesuch" to search for matches diff --git a/test/cases/repl-help/0008/input b/test/cases/repl-help/0008/input new file mode 100644 index 000000000..6758fb508 --- /dev/null +++ b/test/cases/repl-help/0008/input @@ -0,0 +1 @@ +:help find nonesuch diff --git a/test/cases/repl-help/0009/cmd b/test/cases/repl-help/0009/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0009/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0009/experr b/test/cases/repl-help/0009/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0009/expout b/test/cases/repl-help/0009/expout new file mode 100644 index 000000000..1a1a7ecd6 --- /dev/null +++ b/test/cases/repl-help/0009/expout @@ -0,0 +1,5 @@ +No help available for nonesuch. Try ":help find nonesuch" to search for matches +asin (class=math #args=1) Inverse trigonometric sine. +asinh (class=math #args=1) Inverse hyperbolic sine. +sin (class=math #args=1) Trigonometric sine. +sinh (class=math #args=1) Hyperbolic sine. diff --git a/test/cases/repl-help/0009/input b/test/cases/repl-help/0009/input new file mode 100644 index 000000000..2c1ceade8 --- /dev/null +++ b/test/cases/repl-help/0009/input @@ -0,0 +1 @@ +:help find nonesuch sin diff --git a/test/cases/repl-help/0010/cmd b/test/cases/repl-help/0010/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0010/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0010/experr b/test/cases/repl-help/0010/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0010/expout b/test/cases/repl-help/0010/expout new file mode 100644 index 000000000..cf7c24ab1 --- /dev/null +++ b/test/cases/repl-help/0010/expout @@ -0,0 +1,5 @@ +acos (class=math #args=1) Inverse trigonometric cosine. +acosh (class=math #args=1) Inverse hyperbolic cosine. +cos (class=math #args=1) Trigonometric cosine. +cosh (class=math #args=1) Hyperbolic cosine. +No help available for nonesuch. Try ":help find nonesuch" to search for matches diff --git a/test/cases/repl-help/0010/input b/test/cases/repl-help/0010/input new file mode 100644 index 000000000..4735fd0e8 --- /dev/null +++ b/test/cases/repl-help/0010/input @@ -0,0 +1 @@ +:help find cos nonesuch diff --git a/test/cases/repl-help/0011/cmd b/test/cases/repl-help/0011/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0011/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0011/experr b/test/cases/repl-help/0011/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0011/expout b/test/cases/repl-help/0011/expout new file mode 100644 index 000000000..9f5c6b71f --- /dev/null +++ b/test/cases/repl-help/0011/expout @@ -0,0 +1,15 @@ +for: defines a for-loop using one of three styles. The body statements must +be wrapped in curly braces. +For-loop over stream record: + + Example: 'for (k, v in $*) { ... }' + +For-loop over out-of-stream variables: + + Example: 'for (k, v in @counts) { ... }' + Example: 'for ((k1, k2), v in @counts) { ... }' + Example: 'for ((k1, k2, k3), v in @*) { ... }' + +C-style for-loop: + + Example: 'for (var i = 0, var b = 1; i < 10; i += 1, b *= 2) { ... }' diff --git a/test/cases/repl-help/0011/input b/test/cases/repl-help/0011/input new file mode 100644 index 000000000..3b352ca73 --- /dev/null +++ b/test/cases/repl-help/0011/input @@ -0,0 +1 @@ +:help for diff --git a/test/cases/repl-help/0012/cmd b/test/cases/repl-help/0012/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0012/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0012/experr b/test/cases/repl-help/0012/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0012/expout b/test/cases/repl-help/0012/expout new file mode 100644 index 000000000..9f5c6b71f --- /dev/null +++ b/test/cases/repl-help/0012/expout @@ -0,0 +1,15 @@ +for: defines a for-loop using one of three styles. The body statements must +be wrapped in curly braces. +For-loop over stream record: + + Example: 'for (k, v in $*) { ... }' + +For-loop over out-of-stream variables: + + Example: 'for (k, v in @counts) { ... }' + Example: 'for ((k1, k2), v in @counts) { ... }' + Example: 'for ((k1, k2, k3), v in @*) { ... }' + +C-style for-loop: + + Example: 'for (var i = 0, var b = 1; i < 10; i += 1, b *= 2) { ... }' diff --git a/test/cases/repl-help/0012/input b/test/cases/repl-help/0012/input new file mode 100644 index 000000000..57c25123e --- /dev/null +++ b/test/cases/repl-help/0012/input @@ -0,0 +1 @@ +:help find for diff --git a/test/cases/repl-help/0013/cmd b/test/cases/repl-help/0013/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0013/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0013/experr b/test/cases/repl-help/0013/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0013/expout b/test/cases/repl-help/0013/expout new file mode 100644 index 000000000..4f922d64b --- /dev/null +++ b/test/cases/repl-help/0013/expout @@ -0,0 +1 @@ +No help available for sec2 diff --git a/test/cases/repl-help/0013/input b/test/cases/repl-help/0013/input new file mode 100644 index 000000000..94ea514c3 --- /dev/null +++ b/test/cases/repl-help/0013/input @@ -0,0 +1 @@ +:help sec2 diff --git a/test/cases/repl-help/0014/cmd b/test/cases/repl-help/0014/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0014/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0014/experr b/test/cases/repl-help/0014/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0014/expout b/test/cases/repl-help/0014/expout new file mode 100644 index 000000000..a710a4f26 --- /dev/null +++ b/test/cases/repl-help/0014/expout @@ -0,0 +1,22 @@ +fsec2dhms (class=time #args=1) Formats floating-point seconds as in fsec2dhms(500000.25) = "5d18h53m20.250000s" +fsec2hms (class=time #args=1) Formats floating-point seconds as in fsec2hms(5000.25) = "01:23:20.250000" +sec2dhms (class=time #args=1) Formats integer seconds as in sec2dhms(500000) = "5d18h53m20s" +sec2gmt (class=time #args=1,2) Formats seconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part. +Examples: +sec2gmt(1234567890) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456, 6) = "2009-02-13T23:31:30.123456Z" +sec2gmtdate (class=time #args=1) Formats seconds since epoch (integer part) as GMT timestamp with year-month-date. Leaves non-numbers as-is. +Example: +sec2gmtdate(1440768801.7) = "2015-08-28". +sec2hms (class=time #args=1) Formats integer seconds as in sec2hms(5000) = "01:23:20" +sec2localdate (class=time #args=1,2) Formats seconds since epoch (integer part) as local timestamp with year-month-date. Leaves non-numbers as-is. Consults $TZ environment variable unless second argument is supplied. +Examples: +sec2localdate(1440768801.7) = "2015-08-28" with TZ="Asia/Istanbul" +sec2localdate(1440768801.7, "Asia/Istanbul") = "2015-08-28" +sec2localtime (class=time #args=1,2,3) Formats seconds since epoch (integer part) as local timestamp. Consults $TZ environment variable unless third argument is supplied. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part +Examples: +sec2localtime(1234567890) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul" +sec2localtime(1234567890.123456) = "2009-02-14 01:31:30" with TZ="Asia/Istanbul" +sec2localtime(1234567890.123456, 6) = "2009-02-14 01:31:30.123456" with TZ="Asia/Istanbul" +sec2localtime(1234567890.123456, 6, "Asia/Istanbul") = "2009-02-14 01:31:30.123456" diff --git a/test/cases/repl-help/0014/input b/test/cases/repl-help/0014/input new file mode 100644 index 000000000..dee6765ad --- /dev/null +++ b/test/cases/repl-help/0014/input @@ -0,0 +1 @@ +:help find sec2 diff --git a/test/cases/repl-help/0015/cmd b/test/cases/repl-help/0015/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0015/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0015/experr b/test/cases/repl-help/0015/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0015/expout b/test/cases/repl-help/0015/expout new file mode 100644 index 000000000..e0b453374 --- /dev/null +++ b/test/cases/repl-help/0015/expout @@ -0,0 +1,5 @@ +sec2gmt (class=time #args=1,2) Formats seconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part. +Examples: +sec2gmt(1234567890) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456, 6) = "2009-02-13T23:31:30.123456Z" diff --git a/test/cases/repl-help/0015/input b/test/cases/repl-help/0015/input new file mode 100644 index 000000000..c1b7fa9de --- /dev/null +++ b/test/cases/repl-help/0015/input @@ -0,0 +1 @@ +:help sec2gmt diff --git a/test/cases/repl-help/0016/cmd b/test/cases/repl-help/0016/cmd new file mode 100644 index 000000000..f17dba06d --- /dev/null +++ b/test/cases/repl-help/0016/cmd @@ -0,0 +1 @@ +mlr repl < ./${CASEDIR}/input diff --git a/test/cases/repl-help/0016/experr b/test/cases/repl-help/0016/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/repl-help/0016/expout b/test/cases/repl-help/0016/expout new file mode 100644 index 000000000..ad1e26c87 --- /dev/null +++ b/test/cases/repl-help/0016/expout @@ -0,0 +1,8 @@ +sec2gmt (class=time #args=1,2) Formats seconds since epoch as GMT timestamp. Leaves non-numbers as-is. With second integer argument n, includes n decimal places for the seconds part. +Examples: +sec2gmt(1234567890) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456) = "2009-02-13T23:31:30Z" +sec2gmt(1234567890.123456, 6) = "2009-02-13T23:31:30.123456Z" +sec2gmtdate (class=time #args=1) Formats seconds since epoch (integer part) as GMT timestamp with year-month-date. Leaves non-numbers as-is. +Example: +sec2gmtdate(1440768801.7) = "2015-08-28". diff --git a/test/cases/repl-help/0016/input b/test/cases/repl-help/0016/input new file mode 100644 index 000000000..ce7f831e8 --- /dev/null +++ b/test/cases/repl-help/0016/input @@ -0,0 +1 @@ +:help find sec2gmt diff --git a/todo.txt b/todo.txt index f6031e43f..bb42991e3 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,6 @@ ================================================================ PUNCHDOWN LIST -* conda issue * blockers: - keep checking issues - verslink old relnotes @@ -12,7 +11,7 @@ PUNCHDOWN LIST - csv irs lf/crlf ignores -- ? already is so? - `mlr put` -> coverart - 0b1011 olh/webdoc - - help approx-match even if exact exists (e.g. 'map') + * release ordering? conda brew macports chocolatey @@ -46,12 +45,7 @@ PUNCHDOWN LIST strptime("1970-01-01T00:00:00.Z", "%Y-%m-%dT%H:%M:%SZ") (error) -* olh - o kw olh for func and funct both - o better help-searching: - ? mlr help search foo -- including flag-search - ? mlr -f foo - ? mlr -F foo == mlr help function foo +* kw olh for func and funct both * pre-release: o check issues