From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from primenet.com.au (ns1.primenet.com.au [203.24.36.2]) by inbox.vuxu.org (OpenSMTPD) with ESMTP id cf7b492d for ; Sat, 4 Jan 2020 15:47:11 +0000 (UTC) Received: (qmail 21339 invoked by alias); 4 Jan 2020 15:47:04 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 45232 Received: (qmail 11718 invoked by uid 1010); 4 Jan 2020 15:47:04 -0000 X-Qmail-Scanner-Diagnostics: from mail-io1-f66.google.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.102.1/25677. spamassassin: 3.4.2. Clear:RC:0(209.85.166.66):SA:0(-2.0/5.0):. Processed in 1.770167 secs); 04 Jan 2020 15:47:04 -0000 X-Envelope-From: roman.perepelitsa@gmail.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: pass (ns1.primenet.com.au: SPF record at _netblocks.google.com designates 209.85.166.66 as permitted sender) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=3hYCwoFS2IMtDsiP8pwLrkz94euyKN4f/lFJihmNtTM=; b=SMxTvKso1TAqj2GOgrywThR2+pRB0Ut5PPXpOjZZPxnvmIONeYdkH7zzLVnnFc0X34 jS9Esd6Rf41ip1wfyT++81wFU+3hGAKcZ6CrsfDCOlx4ohdy1EHU1jQYn6VzT8hRAWSc nxC+ZplbZ4blR9+G134uJTPZM40sdNlKgoNPGFqMsU4nyCeOF/suPYlBgcZyKc/EJI6T nJ1sgSxC3psMfkP1m9hYm3eR3WjNo8IYZlscUjJuVGsePoI9HTYDdBdhaN3m5qEkDsEq dwxM+ENqxQeKivcV7vSlvUThS3kKYZR4MA/ooMUH677QILZErZ/bSqiqWULCNDXHt+h8 4Quw== X-Gm-Message-State: APjAAAUFY0D8MqjnQG5ZGjExeca0N08uk5CdCPjDMiAP2qCpAxhu5jWS UeQ14OmrE5ltD+JayqCXTGY3x7aLsmxDb17Yllr9PdpC X-Google-Smtp-Source: APXvYqy9ykutwto9amhfeg/IUqSXFjZBGvnabDE0e791fo3a65NuaoKXehCzrRi2855GTESWO0BL9GxwYk6fKI9hGn4= X-Received: by 2002:a6b:b941:: with SMTP id j62mr66009489iof.168.1578152788980; Sat, 04 Jan 2020 07:46:28 -0800 (PST) MIME-Version: 1.0 References: <63663202-4b1d-428a-b16b-5be1425e84ef@www.fastmail.com> <0C0C9775-59EE-4FBB-AB84-3E7FEF6E5024@dana.is> <186D63AE-2F2A-41C3-9E09-CEE0714E2B7F@dana.is> <12F64C78-BFA2-460C-80D4-921F22C72F78@dana.is> <1578063609.4581.6.camel@samsung.com> <20200103204856.bv6f3dkqhtrjm6vm@tarpaulin.shahaf.local2> <54205248-124e-4e9a-942f-7ff0626791a6@www.fastmail.com> In-Reply-To: From: Roman Perepelitsa Date: Sat, 4 Jan 2020 16:46:17 +0100 Message-ID: Subject: Re: Official plugin manager? To: dana Cc: Daniel Shahaf , Zsh hackers list Content-Type: text/plain; charset="UTF-8" On Sat, Jan 4, 2020 at 1:40 AM dana wrote: > Actually, if key bindings don't always work well out of the box, and > especially if we can fix that by simply checking terminfo, shouldn't we do > that with the default bindings in the shell itself? If keys such as arrows, home, end and delete just worked, this would be perfect! My comment presupposed the existing zsh, which requires a few bindkey commands to make these keys work. The use of terminfo here results in brittle code. Let me show what I mean. ${terminfo[khome]} expands to the escape sequence for the home key. Let's try using it: autoload -Uz terminfo bindkey ${terminfo[khome]} beginning-of-line Doesn't work. Zsh puts terminal in raw mode (rmkx) when it starts but ${terminfo[khome]} is the escape key for application mode (smkx). Let's manually switch terminal to application mode. echoti smkx This works. Until we run an application that switches terminal back to raw mode. To solve this problem we can hook zle-line-init and switch to application mode from there. function zle-line-init () { echoti smkx; } zle -N zle-line-init It's what Debian does. And Oh My Zsh. And Prezto. This works. Until we source a plugin before setting up bindings and the plugin happens to hook zle-line-init. Our zle-line-init overrides the plugin's, breaking it in the process. Let's fix it by calling the plugin's hook from ours. zle -A zle-line-init orig-zle-line-init function my-zle-line-init () { zle orig-zle-line-init echoti smkx } zle -N zle-line-init my-zle-line-init This works. Until we source a plugin after setting up bindings and the plugin happens to hook zle-line-init without calling our hook. This time it's the plugin breaking our code rather than vise versa. The alternative to this rather complex and brittle approach is to bind beginning-of-line to several escape sequences. bindkey '^[[H' beginning-of-line # home in raw mode bindkey '^[OH' beginning-of-line # home in app mode To avoid having to specify bindings several times, we can translate escape sequences from application mode to their counterparts in raw mode, and bind all keys as if the terminal was always in raw mode. # Translate application mode (smkx) key escape codes, # to raw mode (rmkx). bindkey -s '^[OH' '^[[H' # home bindkey -s '^[OF' '^[[F' # end # etc bindkey '^[[H' beginning-of-line # home bindkey '^[[F' end-of-line # end # etc The same approach works with terminals of different type: # TTY sends different key codes. Translate them to regular. bindkey -s '^[[1~' '^[[H' # home bindkey -s '^[[4~' '^[[F' # end And NumLock: # If NumLock is off, translate keys to make them appear # the same as with NumLock on. bindkey -s '^[OM' '^M' # enter bindkey -s '^[Ok' '+' bindkey -s '^[Om' '-' bindkey -s '^[Oj' '*' bindkey -s '^[Oo' '/' bindkey -s '^[OX' '=' This makes keys such as `/` and `+` on the numpad work in zsh the same way they work everywhere else. The downside of such shotgun-type translation is the possibility of clashes. It's possible in theory that one terminal's escape code for the home key is another terminal's code for the end key. This can be dealt with with some conditionals. I don't have any in my own zshrc as none of the terminals I use produce clashes on any key sequences. I imagine not everyone is so lucky. > Obviously we shouldn't go crazy with it, but i don't see any reason to > specifically limit the use of styles. The style system is an important aspect > of configuring zsh. There are very useful settings that can only be changed > that way, and it's important for users to know about it if they want to make > their own changes. Oh yeah, I've nothing against styles. I wanted (but failed) to make a point that the basic config shouldn't attempt to provide the best possible shell experience at the expense of config complexity. If 12 completion style lines give you only slightly better completion that 2 lines, it may be preferable to go with 2 lines. When the user's complexity threshold is exceeded by the config, the whole thing becomes opaque. A slightly worse but simpler config may result in better long term user experience as the user will be able to customize it. Roman.