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 autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 22228 invoked from network); 10 Sep 2023 18:23:11 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 10 Sep 2023 18:23:11 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1694370191; b=rRnr9W//wpjADSllb55DW3VEVCk95OU0pnBYHJoeK2ZQmhxXxLrA49x51DgBM9dIiz+tXdRdaJ 9i7X6rwZiFcjJ9KaSlUGbhEhSIqkXIgXGacpJ7Xs2cZlPMuB155xascEYndt1feqZjQ4xoc1N/ nSvgBitcynaPI9uxScZcRtZLv8BE+kxGsFZYeZGECalHbGEZyGydeg4hKfkzFbVMP0rbCzV0RL bH8Rcu/457wLWZH2T9AKSSHdGwZvXfVEb/6oAOOh/Fj5get+W+e/ko93TjLVyTx+ROxvR2Y5kg SHVqPvj8U5hK61KwUSgPwziVrFCuvRO6TTjwEZ7fU7xfOA==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (mail-lj1-f175.google.com) smtp.remote-ip=209.85.208.175; dkim=pass header.d=brasslantern-com.20230601.gappssmtp.com header.s=20230601 header.a=rsa-sha256; dmarc=none header.from=brasslantern.com; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20210803; t=1694370191; bh=7kWPTeLsYMnt8rxCuTKNYx39VXGNWIP4j8A9S5uvx3A=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Content-Type:To:Subject:Message-ID:Date:From:MIME-Version: DKIM-Signature:DKIM-Signature; b=jsItBKSVykl7AjOIs1PhFY66t9FU1//ZG35iDQt91FtBSJQGINa83Af4+vVtU6js92I71IaBjV N5X7weMTaNzltEjnz6TbsH5rxE2t33qIKxaoNmv8zu/pppjgJa9r1cmB6Echa2B+KCpr4l2Tcg dGCSlxtzsLZxpss3psclxhbsHk9Q1tDFuKBLK/AblmFp6c1/CiAPXQ6ydnv3vqejPSp3sqNdcI astcCYZ9b36SlPbmhMe66XxTJMi0XWs+d2fYTFRjzAurKi2IKjZc276ddWbVBk/44tjxS4u+Q6 jD+7gDVV8PLe1jXyt/aBKogG00z13BQoM2egApW9ROCCTw==; 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-Type:To:Subject:Message-ID: Date:From:MIME-Version:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References; bh=2BbMl01XV8CI5ABT7Xo0gwzESDmLGB8PWNPmFqnilK4=; b=eGGXaYrs9yiBX37VMDivaEuI19 d+l/xcB6qmYbt3ac/4luJNZ5/fIEE/1a/PM2uShRuDKKchYxH65EFCvY7P8SYAVX4zNLujdmTGkWt XeTjDHlha05+pceaeQRBkHo/14/MLBnbGaJrdBtu72ha7MJiLhVErpc0yKqrYaAovJipYx14iy6M/ OswMBR0hCny11KETWNXZQv3lQWNdjMglSUwJEGMgH+xomF8NGOarAWcJ1a3A5XvjkJv3FD0HsTKvx nK27feZVjzayKl9KVenaUTTrmOwl6mZO6CsW+K1klgti7z86N03GrmUEqZKwJumiX3G82aV1FP4Ir fiCa0e8g==; Received: by zero.zsh.org with local id 1qfP5R-000Inq-L9; Sun, 10 Sep 2023 18:23:09 +0000 Authentication-Results: zsh.org; iprev=pass (mail-lj1-f175.google.com) smtp.remote-ip=209.85.208.175; dkim=pass header.d=brasslantern-com.20230601.gappssmtp.com header.s=20230601 header.a=rsa-sha256; dmarc=none header.from=brasslantern.com; arc=none Received: from mail-lj1-f175.google.com ([209.85.208.175]:61886) by zero.zsh.org with esmtps (TLS1.3:TLS_AES_128_GCM_SHA256:128) id 1qfP4C-000I9d-M5; Sun, 10 Sep 2023 18:21:58 +0000 Received: by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-2b703a0453fso62671291fa.3 for ; Sun, 10 Sep 2023 11:21:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brasslantern-com.20230601.gappssmtp.com; s=20230601; t=1694370111; x=1694974911; darn=zsh.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=2BbMl01XV8CI5ABT7Xo0gwzESDmLGB8PWNPmFqnilK4=; b=gxfechF1SKPYoWXPVvjea3WzOHMT3QxDrnsaDfebmOBTqAow9XpJ8U4Zb9tpthMujP J5Tj6LvhG6jro5Dm/2YPcmp11eGEbcCnGFc/T2fK+xfolCsK2v0OnPgxQqJiH5JPgScq JVzu9m1MMSDOeZgvwPQiOXmpl60ccMFI7VuFiv6IQGwPO5d6v5+hQyRSNt46zCM7rdcw ceNPR+GjwbjmXhQV6NH8dVwPYnwO7fMEnY4pLhJH6TI2fI0914/OKYh+bWXcqiHeHuxj nrGDHgjx71EGLxyxLMp5t//OBXpgMKTvQ9+XR29HcX7c1CY6/U8YZGm0ivlitrGErIcf RdLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694370111; x=1694974911; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=2BbMl01XV8CI5ABT7Xo0gwzESDmLGB8PWNPmFqnilK4=; b=VTIrB7BwMmalNXIEgH9sqNu+ukIIKgONUngk8zXBdoPXSSTIWIxlkj0cnVijWI59xr T61c89fs7wWnoCTbtpLQdF5dGQzmCjGWlQpW9rIL+VULrlxOJySqejrh+xRPi8oVxrg4 M9ZOcudy6AK5aiK3kW7qKxLLRDeX4Obv3DIoa2KoxKq9luOpnTm0Vf7Lp+24bPXCnjDr rj/Y0FkVqORnnqWfO10RzzDZgGoQP4+lOpXM8iGE7+47G1nBa/Oxl0CNE70qN7gsp4Ro qkeL9cd4r77JBNRvNuiMUxmUjj5Zg2PLsrERESFBvdj0CZSC7za99rHHhvUWeTKKCYah Qu2w== X-Gm-Message-State: AOJu0YyU9sGPMVCL+CwNXZq4t9yEnb8g+L4KKLoarIl81W6bGbaTFBCF VwRAzsuUlFdv3ZeC1s6rumm52lg21kWwtnIXodHhF+b6iUE2OXFtFjU= X-Google-Smtp-Source: AGHT+IH3zvVBzfuFDDoe5zZ5NkrCvKQSNkiiJO0IMyWGiWi7fuqsabSaJML803Ypoy+i+0PAktXC/oysoNp+MJLs17A= X-Received: by 2002:a2e:7d12:0:b0:2b9:e230:25ce with SMTP id y18-20020a2e7d12000000b002b9e23025cemr6831974ljc.12.1694370111396; Sun, 10 Sep 2023 11:21:51 -0700 (PDT) MIME-Version: 1.0 From: Bart Schaefer Date: Sun, 10 Sep 2023 11:21:40 -0700 Message-ID: Subject: Things you can do with mkshadow To: Zsh Users Content-Type: text/plain; charset="UTF-8" X-Seq: 29228 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: I'm not really sure where else to put this, so putting it here. Briefly, the mkshadow utility creates a "shadow copy" of a function, builtin, or command so that it can be locally redefined. (Anything not a function or builtin is presumed to be a command.) The canonical usage is something like hello() { print Hello, world } greeting() { hello } howdy() { { mkshadow hello hello() { print Howdy, pardner } greeting } always { rmshadow } } Calling rmshadow undoes everything back to the most recent call to mkshadow, so the use of an "always" block is a good way to assure the two are called in matching pairs. However, this isn't required. For example, the local redefinition can unmask itself: howdy() { { mkshadow hello hello() { print Howdy, pardner { rmshadow greeting } always { mkshadow hello } } greeting } always { rmshadow } } This makes the internal redefinition of "hello" behave like a locally-scoped function. Whenever it's called from "howdy" it removes the shadow copy so that anything it might call sees the original definition of "hello". It then restores the shadow so that "howdy" can safely remove it again. There's an extra nuance available, which is that mkshadow can be told how to name the shadow copy. howdy() { { mkshadow -s howdy hello hello() { print Howdy, pardner } greeting } always { rmshadow } } Without the -s option, a new shadow copy is created on every call, so for example in recursive functions you can end up with shadows of shadows. With -s, a new copy is created only on the first call, but the number of mkshadow calls is still remembered, so rmshadow will not restore the original function until the full stack is unwound. This is most useful when the redefined function wants to call the original -- note how the shadow name is appended to the original name to create the new function: howdy() { { mkshadow -s howdy hello hello() { print Howdy, pardner hello@howdy } greeting } always { rmshadow } } Even without -s you can access the most-recently shadowed function by capturing the value of $REPLY following the call to mkshadow. howdy() { { mkshadow hello local hellofn="hello@$REPLY" hello() { print Howdy, pardner $hellofn } greeting } always { rmshadow } } As a final hint, rmshadow also sets $REPLY to the name set by the most recent mkshadow, which is handy for the locally-scoped function trick. howdy() { { mkshadow -s howdy hello hello() { print Howdy, pardner { rmshadow local shadow=$REPLY greeting } always { mkshadow -s $shadow hello } } greeting } always { rmshadow } } For those not on zsh-workers, mkshadow can be found here: https://raw.githubusercontent.com/zsh-users/zsh/master/Functions/Misc/mkshadow https://raw.githubusercontent.com/zsh-users/zsh/master/Completion/Base/Utility/_shadow It uses a new feature developed in March - June 2023, so to make it compatible with current released versions as of this posting, run sed -e 's/\.shadow\./_shadow_/g' < _shadow > _shadow-5_9 mv _shadow-5_9 _shadow