mirror of
https://github.com/wader/fq.git
synced 2024-12-23 05:13:30 +03:00
interp: Don't print context cancel
This commit is contained in:
parent
80b5d66c7a
commit
13fae09172
@ -13,6 +13,7 @@
|
||||
- `echo '{} {} {}' | jq` vs `echo '{} {} {}' | fq` works differently. fq currently decodes one root format and might add unknown fields etc. Maybe should work differently for `json` format?
|
||||
- `format/0` overlap with jq builtin `format/1`. What to rename it to? `decode_format`?
|
||||
- repl expression returning a value that produced lots of output can't be interrupted. This is becaus ctrl-C currently only interrupts the evaluation of the expression, outputted value is printed (`display`) by parent.
|
||||
- Rework cli/repl user interrupt (context cancel via ctrl-c), see comment in Interp.Main
|
||||
|
||||
### TODO and ideas
|
||||
|
||||
|
@ -26,11 +26,11 @@ type fuzzTestOutput struct {
|
||||
func (o fuzzTestOutput) Size() (int, int) { return 120, 25 }
|
||||
func (o fuzzTestOutput) IsTerminal() bool { return false }
|
||||
|
||||
func (ft *fuzzTest) Stdin() io.Reader { return bytes.NewBuffer(ft.b) } // TODO: special file?
|
||||
func (ft *fuzzTest) Stdout() interp.Output { return fuzzTestOutput{os.Stdout} }
|
||||
func (ft *fuzzTest) Stderr() io.Writer { return os.Stderr }
|
||||
func (ft *fuzzTest) Interrupt() chan struct{} { return nil }
|
||||
func (ft *fuzzTest) Environ() []string { return nil }
|
||||
func (ft *fuzzTest) Stdin() io.Reader { return bytes.NewBuffer(ft.b) } // TODO: special file?
|
||||
func (ft *fuzzTest) Stdout() interp.Output { return fuzzTestOutput{os.Stdout} }
|
||||
func (ft *fuzzTest) Stderr() io.Writer { return os.Stderr }
|
||||
func (ft *fuzzTest) InterruptChan() chan struct{} { return nil }
|
||||
func (ft *fuzzTest) Environ() []string { return nil }
|
||||
func (ft *fuzzTest) Args() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ func (cr *CaseRun) Stderr() interp.Output {
|
||||
return CaseRunOutput{Writer: cr.ActualStderrBuf}
|
||||
}
|
||||
|
||||
func (cr *CaseRun) Interrupt() chan struct{} { return nil }
|
||||
func (cr *CaseRun) InterruptChan() chan struct{} { return nil }
|
||||
|
||||
func (cr *CaseRun) Environ() []string {
|
||||
env := []string{
|
||||
|
@ -34,9 +34,8 @@ func (a autoCompleterFn) Do(line []rune, pos int) (newLine [][]rune, length int)
|
||||
}
|
||||
|
||||
type stdOS struct {
|
||||
rl *readline.Instance
|
||||
interruptSignalChan chan os.Signal
|
||||
interruptChan chan struct{}
|
||||
rl *readline.Instance
|
||||
interruptChan chan struct{}
|
||||
}
|
||||
|
||||
func newStandardOS() *stdOS {
|
||||
@ -44,7 +43,10 @@ func newStandardOS() *stdOS {
|
||||
interruptSignalChan := make(chan os.Signal, 1)
|
||||
signal.Notify(interruptSignalChan, os.Interrupt)
|
||||
go func() {
|
||||
defer signal.Stop(interruptSignalChan)
|
||||
defer func() {
|
||||
signal.Stop(interruptSignalChan)
|
||||
close(interruptSignalChan)
|
||||
}()
|
||||
for range interruptSignalChan {
|
||||
select {
|
||||
case interruptChan <- struct{}{}:
|
||||
@ -54,8 +56,7 @@ func newStandardOS() *stdOS {
|
||||
}()
|
||||
|
||||
return &stdOS{
|
||||
interruptSignalChan: interruptSignalChan,
|
||||
interruptChan: interruptChan,
|
||||
interruptChan: interruptChan,
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +115,7 @@ func (o stderrOutput) Write(p []byte) (n int, err error) { return os.Stderr.Writ
|
||||
|
||||
func (o *stdOS) Stderr() interp.Output { return stderrOutput{fdTerminal: fdTerminal(os.Stderr.Fd())} }
|
||||
|
||||
func (o *stdOS) Interrupt() chan struct{} { return o.interruptChan }
|
||||
func (o *stdOS) InterruptChan() chan struct{} { return o.interruptChan }
|
||||
|
||||
func (*stdOS) Args() []string { return os.Args }
|
||||
|
||||
@ -204,7 +205,7 @@ func (o *stdOS) Close() error {
|
||||
if o.rl != nil {
|
||||
o.rl.Close()
|
||||
}
|
||||
close(o.interruptSignalChan)
|
||||
close(o.interruptChan)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -121,5 +121,7 @@ def _decode_value(f):
|
||||
else _expected_decode_value
|
||||
end;
|
||||
|
||||
def _is_context_canceled_error: . == "context canceled";
|
||||
|
||||
def _error_str: "error: \(.)";
|
||||
def _errorln: ., "\n" | stderr;
|
||||
|
@ -106,7 +106,7 @@ type OS interface {
|
||||
Stdin() Input
|
||||
Stdout() Output
|
||||
Stderr() Output
|
||||
Interrupt() chan struct{}
|
||||
InterruptChan() chan struct{}
|
||||
Args() []string
|
||||
Environ() []string
|
||||
ConfigDir() (string, error)
|
||||
@ -446,7 +446,7 @@ func New(os OS, registry *registry.Registry) (*Interp, error) {
|
||||
select {
|
||||
case <-stopCh:
|
||||
return
|
||||
case <-os.Interrupt():
|
||||
case <-os.InterruptChan():
|
||||
return
|
||||
}
|
||||
})
|
||||
@ -486,6 +486,10 @@ func (i *Interp) Main(ctx context.Context, output Output, version string) error
|
||||
case error:
|
||||
if emptyErr, ok := v.(IsEmptyErrorer); ok && emptyErr.IsEmptyError() { //nolint:errorlint
|
||||
// no output
|
||||
} else if errors.Is(v, context.Canceled) {
|
||||
// ignore context cancel here for now, which means user somehow interrupted the interpreter
|
||||
// TODO: handle this inside interp.jq instead but then we probably have to do nested
|
||||
// eval and or also use different contexts for the interpreter and reading/decoding
|
||||
} else {
|
||||
fmt.Fprintln(i.os.Stderr(), v)
|
||||
}
|
||||
|
@ -155,7 +155,10 @@ def _prompt:
|
||||
|
||||
def _repl_display: _display({depth: 1});
|
||||
def _repl_on_error:
|
||||
( if _eval_is_compile_error then _eval_compile_error_tostring end
|
||||
( if _eval_is_compile_error then _eval_compile_error_tostring
|
||||
# was interrupte by user, just ignore
|
||||
elif _is_context_canceled_error then empty
|
||||
end
|
||||
| (_error_str | println)
|
||||
);
|
||||
def _repl_on_compile_error: _repl_on_error;
|
||||
|
Loading…
Reference in New Issue
Block a user