From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 25791 invoked from network); 11 Feb 2022 00:05:19 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 11 Feb 2022 00:05:19 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1644537919; b=aeSeLcQnWFYu2ipxtdeTCzE8qx5wKAEeb4A6UkGbBh4jeIzx1O6bevjBiFMNu7ynTm6mUL5S0m DYD4Z5IvG+G2Vus8yl2mGxMCTlkzTOr8TE4NppV1RQ8pjFRiRWz8RjUq+6C54n1VQhrxjNX+uR nEGPLyCNBXjrJdpmtY/ehEWBtn7yYc/VXGrjpckJYO0UjNUO91ai29dj26SCTEkSIgn9v/evO5 ZnsVgiRM6IoKfEdU2K5+go0d/VyhxoKVRG+oVM2NDH73/POjCN0yZ9wE3U/bPwy8OAcKdTFVjU 2Tj+zVBSBUNBVqYM4LiaaMqpkCj8i2dWvY5xIohilyojuQ==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (granite.fifsource.com) smtp.remote-ip=173.255.216.206; dmarc=none header.from=fifi.org; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20210803; t=1644537919; bh=MS2Y9w/36Huk7s0ldfdbrzJy4ZNx/IZ7iTcd2ih5S0k=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Content-Transfer-Encoding:MIME-Version:Content-Type: References:In-Reply-To:Date:To:From:Subject:Message-ID:DKIM-Signature; b=m2TqtYAVtHxsXVrNRb85CTKW0Z3YCEksiatwrWtMGzN3+EYH/5tCsSdX/TrsEXAPveD1rfnamx qFuKcfU3ycNN4nMZ+sTk2zYXqTtNVdSF3RgULaB13BSnQ2sSk+5p1vLScUtlrCem6Ay51hwtNI GayeKLOCTYasTpSz3dpaWope5L2KGZkCxIdpnPaS4zR7n+Wg+eeqc7jhs6P/87aQDcSdeOZ65X jO2C/COUtXGYREK2uWP02VQLklDPS3ppIWRkrlDTPBpVi4kMG7VbynVFyqETP40P6PKiKFWwhR VOivT2zoh4nCKAiIYaPfYDVAgsWfyoOcEAs6yOZfzsK5jw==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Content-Transfer-Encoding: MIME-Version:Content-Type:References:In-Reply-To:Date:To:From:Subject: Message-ID:Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From :Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=jd+7nUgbPnWOCqjUz2Nu7cOlnBoQgxGwX7bcGKX1Xy0=; b=CP98zOtGvxxIky7VP9Izkl9NgG NByk7X7hd0CF6bj/XRyQfqsZ6fQ+gywBxRCW+UXNdnc9JFG8CckLy6OpHfsdBV+N7nsblAcJy72Fy 9hf8cknRHsDbWlhiznQ9dvmiqSSgVALqqq2v4InELlhZu4GqIR13M1mlS20hqLQuO2/2AeD63tQ0c 1YKW8ZQpyArh9e4iMZh1SufYZmvSHU0zItMe3sWNAXN6iigyWsLdKi8Indgv/05dkXN/xPKHlqMwb Qc/RwF8i2bki6wjRGbHFIsFS51hg/0LjJcVvzBBtxSWzT5HuvvEnW8S5KKrcjvl1XKPefrAeLZ0/e PxXTUNtQ==; Received: from authenticated user by zero.zsh.org with local id 1nIJR8-0007om-Nl; Fri, 11 Feb 2022 00:05:18 +0000 Authentication-Results: zsh.org; iprev=pass (granite.fifsource.com) smtp.remote-ip=173.255.216.206; dmarc=none header.from=fifi.org; arc=none Received: from granite.fifsource.com ([173.255.216.206]:50938) by zero.zsh.org with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) id 1nIJQZ-00074c-PN; Fri, 11 Feb 2022 00:04:44 +0000 Received: from dyn-019-wlan.home.fifi.org (107-142-44-70.lightspeed.sntcca.sbcglobal.net [107.142.44.70]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by granite.fifsource.com (Postfix) with ESMTPSA id C477C4073; Thu, 10 Feb 2022 16:04:41 -0800 (PST) Message-ID: <24180172015e6c9c3bab278c840eabcaa1a3249f.camel@fifi.org> Subject: Re: Detect typed input without swallowing characters From: Philippe Troin To: Marc =?ISO-8859-1?Q?Cornell=E0?= , zsh-users@zsh.org Date: Thu, 10 Feb 2022 16:04:41 -0800 In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.42.3 (3.42.3-1.fc35) MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Seq: 27509 Archived-At: X-Loop: zsh-users@zsh.org Errors-To: zsh-users-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-users-request@zsh.org X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: On Thu, 2022-02-10 at 22:21 +0100, Marc Cornellà wrote: > in Oh My Zsh we want to detect whether the user has typed characters > before showing the prompt to auto-update, so that if they have, to > skip it entirely and get them to the prompt as fast as possible. > > The current solution is to detect whether there's input with `read -t > -k 1`, but this solution has the downside of swallowing one > character. > > I've been looking at sysread and zselect to poll stdin (fd 0), but I > believe they only tell whether stdin is ready for reading, not > whether > it holds any data. These are the commands I'm using by the way: > >     sysread -t 0 -i 0 >     zselect -t 0 -r 0 > > Is there any way to do this or should I give up entirely? You can use zselect, but you have to disable canonical mode with stty, otherwise characters are not counted unless you press enter (the terminal is set to read a whole line at once). This function should work: type_ahead() { emulate -L zsh local termios=$(stty --save) stty -icanon zselect -t 0 -r 0 local ret=$? stty $termios return ret } There may be subtleties involved with the STTY variable as well as ttyctl, check out the zsh documentation. I only did minimal testing: sleep 5; if type_ahead; then echo TYPED AHEAD; fi works as it should. You can also get the number of bytes in the read buffer with the FIONREAD ioctl() (man ioctl_tty for details). This long python 1-liner does what you want: python -c 'import array, fcntl, termios; nbuffered=array.array("i", [0]); old=termios.tcgetattr(0); new=old[:]; new[3] &= ~termios.ICANON; termios.tcsetattr(0, termios.TCSANOW, new); fcntl.ioctl(0, termios.FIONREAD, nbuffered); termios.tcsetattr(0, termios.TCSANOW, old); print(nbuffered[0])' Same script in a more readable form: #!/usr/bin/env python3 import array, fcntl, termios nbuffered=array.array("i", [0]) old=termios.tcgetattr(0) new=old[:] # Array copy new[3] &= ~termios.ICANON # Disable canonical mode try: # try/finally cannot appear in the 1-liner above termios.tcsetattr(0, termios.TCSANOW, new) fcntl.ioctl(0, termios.FIONREAD, nbuffered) finally: termios.tcsetattr(0, termios.TCSANOW, old) print(nbuffered[0]) I doubt this would be useful for your use case, as firing up the whole python interpreter to perform FIONREAD is likely to be slower than the optimization gain you're trying to measure. Phil.