diff --git a/completions/bash b/completions/bash index ccd16ef..2f8e7ad 100644 --- a/completions/bash +++ b/completions/bash @@ -19,7 +19,7 @@ _watchexec() { case "${cmd}" in watchexec) - opts="-w -c -o -r -s -d -p -n -E -1 -N -q -e -f -j -i -v -h -V --watch --clear --on-busy-update --restart --signal --stop-signal --stop-timeout --map-signal --debounce --stdin-quit --no-vcs-ignore --no-project-ignore --no-global-ignore --no-default-ignore --no-discover-ignore --ignore-nothing --postpone --delay-run --poll --shell --no-environment --emit-events-to --only-emit-events --env --no-process-group --notify --color --timings --quiet --bell --project-origin --workdir --exts --filter --filter-file --filter-prog --ignore --ignore-file --fs-events --no-meta --print-events --verbose --log-file --manual --completions --help --version [COMMAND]..." + opts="-w -c -o -r -s -d -p -n -E -1 -N -q -e -f -j -i -v -h -V --watch --clear --on-busy-update --restart --signal --stop-signal --stop-timeout --map-signal --debounce --stdin-quit --no-vcs-ignore --no-project-ignore --no-global-ignore --no-default-ignore --no-discover-ignore --ignore-nothing --postpone --delay-run --poll --shell --no-environment --emit-events-to --only-emit-events --env --no-process-group --wrap-process --notify --color --timings --quiet --bell --project-origin --workdir --exts --filter --filter-file --filter-prog --ignore --ignore-file --fs-events --no-meta --print-events --verbose --log-file --manual --completions --help --version [COMMAND]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -101,6 +101,10 @@ _watchexec() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --wrap-process) + COMPREPLY=($(compgen -W "group session none" -- "${cur}")) + return 0 + ;; --color) COMPREPLY=($(compgen -W "auto always never" -- "${cur}")) return 0 diff --git a/completions/elvish b/completions/elvish index 48ac72b..ce7ebc4 100644 --- a/completions/elvish +++ b/completions/elvish @@ -37,6 +37,7 @@ set edit:completion:arg-completer[watchexec] = {|@words| cand --emit-events-to 'Configure event emission' cand -E 'Add env vars to the command' cand --env 'Add env vars to the command' + cand --wrap-process 'Configure how the process is wrapped' cand --color 'When to use terminal colours' cand --project-origin 'Set the project origin' cand --workdir 'Set the working directory' diff --git a/completions/fish b/completions/fish index aa02838..c29c8ca 100644 --- a/completions/fish +++ b/completions/fish @@ -11,6 +11,7 @@ complete -c watchexec -l poll -d 'Poll for filesystem changes' -r complete -c watchexec -l shell -d 'Use a different shell' -r complete -c watchexec -l emit-events-to -d 'Configure event emission' -r -f -a "{environment '',stdio '',file '',json-stdio '',json-file '',none ''}" complete -c watchexec -s E -l env -d 'Add env vars to the command' -r +complete -c watchexec -l wrap-process -d 'Configure how the process is wrapped' -r -f -a "{group '',session '',none ''}" complete -c watchexec -l color -d 'When to use terminal colours' -r -f -a "{auto '',always '',never ''}" complete -c watchexec -l project-origin -d 'Set the project origin' -r -f -a "(__fish_complete_directories)" complete -c watchexec -l workdir -d 'Set the working directory' -r -f -a "(__fish_complete_directories)" diff --git a/completions/nu b/completions/nu index 583cf71..45f76ab 100644 --- a/completions/nu +++ b/completions/nu @@ -12,6 +12,10 @@ module completions { [ "environment" "stdio" "file" "json-stdio" "json-file" "none" ] } + def "nu-complete watchexec wrap_process" [] { + [ "group" "session" "none" ] + } + def "nu-complete watchexec color" [] { [ "auto" "always" "never" ] } @@ -53,6 +57,7 @@ module completions { --only-emit-events # Only emit events to stdout, run no commands --env(-E): string # Add env vars to the command --no-process-group # Don't use a process group + --wrap-process: string@"nu-complete watchexec wrap_process" # Configure how the process is wrapped -1 # Testing only: exit Watchexec after the first run --notify(-N) # Alert when commands start and end --color: string@"nu-complete watchexec color" # When to use terminal colours diff --git a/completions/powershell b/completions/powershell index d2f8678..fb7f861 100644 --- a/completions/powershell +++ b/completions/powershell @@ -40,6 +40,7 @@ Register-ArgumentCompleter -Native -CommandName 'watchexec' -ScriptBlock { [CompletionResult]::new('--emit-events-to', 'emit-events-to', [CompletionResultType]::ParameterName, 'Configure event emission') [CompletionResult]::new('-E', 'E ', [CompletionResultType]::ParameterName, 'Add env vars to the command') [CompletionResult]::new('--env', 'env', [CompletionResultType]::ParameterName, 'Add env vars to the command') + [CompletionResult]::new('--wrap-process', 'wrap-process', [CompletionResultType]::ParameterName, 'Configure how the process is wrapped') [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'When to use terminal colours') [CompletionResult]::new('--project-origin', 'project-origin', [CompletionResultType]::ParameterName, 'Set the project origin') [CompletionResult]::new('--workdir', 'workdir', [CompletionResultType]::ParameterName, 'Set the working directory') diff --git a/completions/zsh b/completions/zsh index a7ebb08..1cf9db9 100644 --- a/completions/zsh +++ b/completions/zsh @@ -34,6 +34,7 @@ _watchexec() { '--emit-events-to=[Configure event emission]:MODE:(environment stdio file json-stdio json-file none)' \ '*-E+[Add env vars to the command]:KEY=VALUE: ' \ '*--env=[Add env vars to the command]:KEY=VALUE: ' \ +'--wrap-process=[Configure how the process is wrapped]:MODE:(group session none)' \ '--color=[When to use terminal colours]:MODE:(auto always never)' \ '--project-origin=[Set the project origin]:DIRECTORY:_files -/' \ '--workdir=[Set the working directory]:DIRECTORY:_files -/' \ diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index 40e731f..4f1065e 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -636,12 +636,31 @@ pub struct Args { /// By default, Watchexec will run the command in a process group, so that signals and /// terminations are sent to all processes in the group. Sometimes that's not what you want, and /// you can disable the behaviour with this option. + /// + /// Deprecated, use '--wrap-process=none' instead. #[arg( long, help_heading = OPTSET_COMMAND, )] pub no_process_group: bool, + /// Configure how the process is wrapped + /// + /// By default, Watchexec will run the command in a process group in Unix, and in a Job Object + /// in Windows. + /// + /// Some Unix programs prefer running in a session, while others do not work in a process group. + /// + /// Use 'group' to use a process group, 'session' to use a process session, and 'none' to run + /// the command directly. On Windows, either of 'group' or 'session' will use a Job Object. + #[arg( + long, + help_heading = OPTSET_COMMAND, + value_name = "MODE", + default_value = "group", + )] + pub wrap_process: WrapMode, + /// Testing only: exit Watchexec after the first run #[arg(short = '1', hide = true)] pub once: bool, @@ -999,6 +1018,14 @@ pub enum OnBusyUpdate { Signal, } +#[derive(Clone, Copy, Debug, Default, ValueEnum)] +pub enum WrapMode { + #[default] + Group, + Session, + None, +} + #[derive(Clone, Copy, Debug, Default, ValueEnum)] pub enum ClearMode { #[default] @@ -1171,6 +1198,10 @@ pub async fn get_args() -> Result { args.emit_events_to = EmitEvents::None; } + if args.no_process_group { + args.wrap_process = WrapMode::None; + } + if args.filter_fs_meta { args.filter_fs_events = vec![ FsEvent::Create, diff --git a/crates/cli/src/config.rs b/crates/cli/src/config.rs index c3e3e01..41a4620 100644 --- a/crates/cli/src/config.rs +++ b/crates/cli/src/config.rs @@ -32,7 +32,7 @@ use watchexec_events::{Event, Keyboard, ProcessEnd, Tag}; use watchexec_signals::Signal; use crate::{ - args::{Args, ClearMode, ColourMode, EmitEvents, OnBusyUpdate, SignalMapping}, + args::{Args, ClearMode, ColourMode, EmitEvents, OnBusyUpdate, SignalMapping, WrapMode}, state::RotatingTempFile, }; use crate::{emits::events_to_simple_format, state::State}; @@ -545,7 +545,8 @@ fn interpret_command_args(args: &Args) -> Result> { Ok(Arc::new(Command { program, options: SpawnOptions { - grouped: !args.no_process_group, + grouped: matches!(args.wrap_process, WrapMode::Group), + session: matches!(args.wrap_process, WrapMode::Session), ..Default::default() }, })) diff --git a/doc/watchexec.1 b/doc/watchexec.1 index 714a896..b4831f7 100644 --- a/doc/watchexec.1 +++ b/doc/watchexec.1 @@ -4,7 +4,7 @@ .SH NAME watchexec \- Execute commands when watched files change .SH SYNOPSIS -\fBwatchexec\fR [\fB\-w\fR|\fB\-\-watch\fR] [\fB\-c\fR|\fB\-\-clear\fR] [\fB\-o\fR|\fB\-\-on\-busy\-update\fR] [\fB\-r\fR|\fB\-\-restart\fR] [\fB\-s\fR|\fB\-\-signal\fR] [\fB\-\-stop\-signal\fR] [\fB\-\-stop\-timeout\fR] [\fB\-\-map\-signal\fR] [\fB\-d\fR|\fB\-\-debounce\fR] [\fB\-\-stdin\-quit\fR] [\fB\-\-no\-vcs\-ignore\fR] [\fB\-\-no\-project\-ignore\fR] [\fB\-\-no\-global\-ignore\fR] [\fB\-\-no\-default\-ignore\fR] [\fB\-\-no\-discover\-ignore\fR] [\fB\-\-ignore\-nothing\fR] [\fB\-p\fR|\fB\-\-postpone\fR] [\fB\-\-delay\-run\fR] [\fB\-\-poll\fR] [\fB\-\-shell\fR] [\fB\-n \fR] [\fB\-\-emit\-events\-to\fR] [\fB\-\-only\-emit\-events\fR] [\fB\-E\fR|\fB\-\-env\fR] [\fB\-\-no\-process\-group\fR] [\fB\-N\fR|\fB\-\-notify\fR] [\fB\-\-color\fR] [\fB\-\-timings\fR] [\fB\-q\fR|\fB\-\-quiet\fR] [\fB\-\-bell\fR] [\fB\-\-project\-origin\fR] [\fB\-\-workdir\fR] [\fB\-e\fR|\fB\-\-exts\fR] [\fB\-f\fR|\fB\-\-filter\fR] [\fB\-\-filter\-file\fR] [\fB\-j\fR|\fB\-\-filter\-prog\fR] [\fB\-i\fR|\fB\-\-ignore\fR] [\fB\-\-ignore\-file\fR] [\fB\-\-fs\-events\fR] [\fB\-\-no\-meta\fR] [\fB\-\-print\-events\fR] [\fB\-v\fR|\fB\-\-verbose\fR]... [\fB\-\-log\-file\fR] [\fB\-\-manual\fR] [\fB\-\-completions\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fICOMMAND\fR] +\fBwatchexec\fR [\fB\-w\fR|\fB\-\-watch\fR] [\fB\-c\fR|\fB\-\-clear\fR] [\fB\-o\fR|\fB\-\-on\-busy\-update\fR] [\fB\-r\fR|\fB\-\-restart\fR] [\fB\-s\fR|\fB\-\-signal\fR] [\fB\-\-stop\-signal\fR] [\fB\-\-stop\-timeout\fR] [\fB\-\-map\-signal\fR] [\fB\-d\fR|\fB\-\-debounce\fR] [\fB\-\-stdin\-quit\fR] [\fB\-\-no\-vcs\-ignore\fR] [\fB\-\-no\-project\-ignore\fR] [\fB\-\-no\-global\-ignore\fR] [\fB\-\-no\-default\-ignore\fR] [\fB\-\-no\-discover\-ignore\fR] [\fB\-\-ignore\-nothing\fR] [\fB\-p\fR|\fB\-\-postpone\fR] [\fB\-\-delay\-run\fR] [\fB\-\-poll\fR] [\fB\-\-shell\fR] [\fB\-n \fR] [\fB\-\-emit\-events\-to\fR] [\fB\-\-only\-emit\-events\fR] [\fB\-E\fR|\fB\-\-env\fR] [\fB\-\-no\-process\-group\fR] [\fB\-\-wrap\-process\fR] [\fB\-N\fR|\fB\-\-notify\fR] [\fB\-\-color\fR] [\fB\-\-timings\fR] [\fB\-q\fR|\fB\-\-quiet\fR] [\fB\-\-bell\fR] [\fB\-\-project\-origin\fR] [\fB\-\-workdir\fR] [\fB\-e\fR|\fB\-\-exts\fR] [\fB\-f\fR|\fB\-\-filter\fR] [\fB\-\-filter\-file\fR] [\fB\-j\fR|\fB\-\-filter\-prog\fR] [\fB\-i\fR|\fB\-\-ignore\fR] [\fB\-\-ignore\-file\fR] [\fB\-\-fs\-events\fR] [\fB\-\-no\-meta\fR] [\fB\-\-print\-events\fR] [\fB\-v\fR|\fB\-\-verbose\fR]... [\fB\-\-log\-file\fR] [\fB\-\-manual\fR] [\fB\-\-completions\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fICOMMAND\fR] .SH DESCRIPTION Execute commands when watched files change. .PP @@ -370,6 +370,17 @@ Use key=value syntax. Multiple variables can be set by repeating the option. Don\*(Aqt use a process group By default, Watchexec will run the command in a process group, so that signals and terminations are sent to all processes in the group. Sometimes that\*(Aqs not what you want, and you can disable the behaviour with this option. + +Deprecated, use \*(Aq\-\-wrap\-process=none\*(Aq instead. +.TP +\fB\-\-wrap\-process\fR=\fIMODE\fR [default: group] +Configure how the process is wrapped + +By default, Watchexec will run the command in a process group in Unix, and in a Job Object in Windows. + +Some Unix programs prefer running in a session, while others do not work in a process group. + +Use \*(Aqgroup\*(Aq to use a process group, \*(Aqsession\*(Aq to use a process session, and \*(Aqnone\*(Aq to run the command directly. On Windows, either of \*(Aqgroup\*(Aq or \*(Aqsession\*(Aq will use a Job Object. .TP \fB\-N\fR, \fB\-\-notify\fR Alert when commands start and end diff --git a/doc/watchexec.1.md b/doc/watchexec.1.md index 71d448f..149887b 100644 --- a/doc/watchexec.1.md +++ b/doc/watchexec.1.md @@ -14,15 +14,16 @@ watchexec - Execute commands when watched files change \[**-p**\|**\--postpone**\] \[**\--delay-run**\] \[**\--poll**\] \[**\--shell**\] \[**-n **\] \[**\--emit-events-to**\] \[**\--only-emit-events**\] \[**-E**\|**\--env**\] -\[**\--no-process-group**\] \[**-N**\|**\--notify**\] \[**\--color**\] -\[**\--timings**\] \[**-q**\|**\--quiet**\] \[**\--bell**\] -\[**\--project-origin**\] \[**\--workdir**\] \[**-e**\|**\--exts**\] -\[**-f**\|**\--filter**\] \[**\--filter-file**\] -\[**-j**\|**\--filter-prog**\] \[**-i**\|**\--ignore**\] -\[**\--ignore-file**\] \[**\--fs-events**\] \[**\--no-meta**\] -\[**\--print-events**\] \[**-v**\|**\--verbose**\]\... -\[**\--log-file**\] \[**\--manual**\] \[**\--completions**\] -\[**-h**\|**\--help**\] \[**-V**\|**\--version**\] \[*COMMAND*\] +\[**\--no-process-group**\] \[**\--wrap-process**\] +\[**-N**\|**\--notify**\] \[**\--color**\] \[**\--timings**\] +\[**-q**\|**\--quiet**\] \[**\--bell**\] \[**\--project-origin**\] +\[**\--workdir**\] \[**-e**\|**\--exts**\] \[**-f**\|**\--filter**\] +\[**\--filter-file**\] \[**-j**\|**\--filter-prog**\] +\[**-i**\|**\--ignore**\] \[**\--ignore-file**\] \[**\--fs-events**\] +\[**\--no-meta**\] \[**\--print-events**\] +\[**-v**\|**\--verbose**\]\... \[**\--log-file**\] \[**\--manual**\] +\[**\--completions**\] \[**-h**\|**\--help**\] +\[**-V**\|**\--version**\] \[*COMMAND*\] # DESCRIPTION @@ -518,6 +519,22 @@ signals and terminations are sent to all processes in the group. Sometimes thats not what you want, and you can disable the behaviour with this option. +Deprecated, use \--wrap-process=none instead. + +**\--wrap-process**=*MODE* \[default: group\] + +: Configure how the process is wrapped + +By default, Watchexec will run the command in a process group in Unix, +and in a Job Object in Windows. + +Some Unix programs prefer running in a session, while others do not work +in a process group. + +Use group to use a process group, session to use a process session, and +none to run the command directly. On Windows, either of group or session +will use a Job Object. + **-N**, **\--notify** : Alert when commands start and end