Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: preexec hook: possible enhancement?



On Sep 5,  8:05pm, Peter Stephenson wrote:
}
} I doubt if there's much joy there... debug traps are called before/after
} every command, including in precmd and preexec, so probably far too
} often.

My thought was to create a TRAPDEBUG function in preexec, and delete it
again in precmd.  Or at least set/clear a variable in those places so
that the function can become an effective no-op when not executing a
pipeline from zle.

} The only argument to a TRAPDEBUG function is the signal number, which
} is meaningless in this case anyway.

I think you mean the *line* number?  What signal's number would it be?

(The argument passed to TRAPDEBUG ought to be documented somewhere, but
is not as far as I can tell.)

The following appears to work for me; the command is printed only if it
runs for at least 1 second, which seems reasonable.  Obviously this is
pretty expensive -- the shell has the information this is digging out of
/proc/*/stat, it just doesn't put it anywhere that TRAPDEBUG can get it.

    find_fg_job() {
      emulate -L zsh
      local x j t
      reply=()

      # Find the TTY of the current shell
      j=( $(</proc/$$/stat) )
      t=$j[7]

      # Return if no TTY
      (( $t )) || return 1

      # Find any other job in the foreground on this TTY
      for x in /proc/<->/stat
      do
        j=()

        # Process might exit between glob and file read,
        # so suppress error messages ...
        j=( $(<$x) ) 2>/dev/null
        # ... and skip this if we can't read it
        (( $#j )) || continue

        # This test skips any sub-shell intermediaries
        [[ $j[2] == "(zsh)" ]] && continue

        # Not this shell and on this TTY and in foreground
        if (( $j[5] != $$ && $j[7] == $t && $j[5] == $j[8] ))
        then
          reply=( ${(ps:\0:)"$(</proc/$j[1]/cmdline)"} )
          return 0
        fi
      done
      return 1
    }

    print_fg_job() {
      find_fg_job || return
      print -u2 "$reply"	# REPLACE THIS WITH TAB TITLE CHANGE
    }

    setopt DEBUG_BEFORE_CMD
    TRAPDEBUG() {
      if [[ -n $DEBUG_FG ]] 
      then
        # Background and disown to suppress job control
        { sleep 1; print_fg_job } &!
      fi
    }

    preexec() { DEBUG_FG="$*" }
    precmd() {
      unset DEBUG_FG
      print -u2 "$0"		# REPLACE THIS WITH TAB TITLE CHANGE
    }



Messages sorted by: Reverse Date, Date, Thread, Author