How to bind clear to ^L in Ksh - ksh

How can i replicate the following bash functionality in KornShell:
bind "\C-l":"clear-screen"
I needed that bind because i'm using set -o vi in bash, and
plan on using it in ksh too.
Trying to use it in ksh prints out an error:
ksh: bind: not found

Sorry to break the news, but as you've noticed this a different between ksh and bash: bind or the ability to define key mappings is not there. Nor is programmable command completion. Historically the Korn shell focused on language design and features and not on interactive terminal capabilities.
GNU bash provides key bindings via the GNU Readline library which was developed and maintained by the same person, Chet Ramey. ksh even in its most recent versions doesn't use this library nor does it provide an equivalant library, as far as I know.
A workaround is to see if you can program the terminal to provide such capabilities. In tmux if you put this in your .tmux.conf configuration file:
bind-key C-l send-keys clear
Then tmux will interpret the Control-l before ksh has a chance to see it and will expand with the string "clear". (Underneath I bet tmux is using the GNU Readline library)
The POSIX standard (which ksh and bash both follow) defines an "alias" command. However an alias name isn't defined to allow control characters. A particular implemenation may do that, but ksh doesn't.
See also https://unix.stackexchange.com/questions/82223/how-to-setup-keyboard-shortcut-that-enters-predefined-text-into-x11-xterminal-vi

Related

Without Emacs, how does Bash command line editing work in Emacs mode?

Without Emacs installed on my Linux system, Bash command line editing default mode is still Emacs. How does this work without Emacs present?
I tried to search the Bash source code, but still can't understand. Does Bash integrate Emacs within itself?
$ set -o
allexport off
braceexpand on
emacs on
: :
vi off
xtrace off
The GNU(1) readline library is what does the heavy lifting for bash (and any other interactive input systems that choose to use it).
That's the source code you should be looking at, if you want to understand how it works.
The readline packages are hosted alongside bash.
(1) Yes, the same GNU that's responsible for the emacs editor.
The reference to emacs has little to do with the emacs editor itself. It refers to the 'style' of key bindings used by the GNU readline library which bash uses. Readline supports two key binding modes - emacs style and vi style. The default is usually emacs style. The readline library is very powerful, but to be honest, in 25 years of Linux use, I've never bothered with most of the advanced features and have never even tried the vi mode (even when VI was my default editor).
Read the section on readline in the bash manual for more details.

Why & How fish does not support POSIX?

I have heard about fish that it's a friendly and out-of-box shell but also it doesn't support POSIX standard.
On the other hand I read about POSIX standard (and also I tested it on my Fedora, It's amazing and out-of-box shell now I want to change my default shell to fish).
But the matter that I opened this question for is: I misunderstood about relation between fish and POSIX standard, what do you mean about fish does NOT support POSIX exactly? & How? (Should I change my bash to fish?).
Please explain it simple 'cause I'm a little newbie, thanks.
fish isn't and never tried to be compatible with POSIX sh.
This really just means that it's a separate language (like Java, Python or Ruby) rather than an implementation or extension of sh (like Bash, Dash and Ksh).
Obviously, just like you can't copy-paste Java snippets into a Python program, you can't copy-paste sh code into fish.
In practice, this means that when you search for things like "how do I show the current git branch in my prompt", you need to make sure you find fish answers because the sh ones won't work. Similarly, when books or instructions give commands to run, you may occasionally need to rewrite some of them manually (or open a bash shell and paste them there).
Whether this matters is entirely up to you, so definitely give it a go.
Actually, fish is not compliant with the POSIX sh definition. But neither is csh (and probably zsh). You still can use fish as your interactive shell.
For example echo $$ shows the pid of the shell in POSIX sh. But with fish it does not.
(and that is why I did not switch to fish and keep using zsh as my daily interactive login shell)
You could change your interactive login shell (using chsh) to fish.
But if you write shell scripts, writing them for the POSIX sh specification make these scripts more portable. (You'll use the shebang #!/bin/sh to start them, it is understood by Linux execve(2)). In some cases, you don't care about portability of your shell script and you could make them start with #!/usr/bin/fish to be fish scripts. Then they won't work on systems without fish.
Also, the system(3) C standard library function uses /bin/sh -c.
I enjoyed very much Yann Regis-Gianas' talk on POSIX [s]hell at FOSDEM2018.

bash: vim mode instead of vi mode?

I noticed when in vi mode in bash (i.e. the mode enabled with "set -o vi"), that some commands, such as "diw", that work in vim but not in vi, don't work on the bash command line. Is there an easy way to configure bash so that its keybindings will support vim commands? I would like to be able to enter vim commands on the command line without having to actually start the vim program, as described in this question.
The best way of doing this that I know of would be to use athame.
It can be a surprisingly powerful experience in some cases. I particularly like it for interacting with a repl.
Athame patches your shell to add full Vim support by routing your keystrokes through an actual Vim process. Athame can currently be used to patch readline (used by bash, gdb, python, etc) and/or zsh (which doesn't use readline).
Alternatively I find spacemacs with the eshell to be a reasonably functional if strange solution.
Teach vi-command-mode diw to any software that uses readline (such as bash) by adding this to your ~/.inputrc:
set keymap vi-command
"diw": "bde"
First, the "vi mode" you get with set -o vi is not vi itself. It's an incomplete approximation of vi's behavior built into readline, the command-line editing library used by bash under the hood.
Second, because it is incomplete there's no reason whatsoever to expect every vi command to work.
Third, no, there's no "vim mode" so even less reason to expect any vim commands to work.
Fourth, if you absolutely want to edit the current command-line with Vim-like commands, why don't you go all the way and… actually use Vim:
<C-x><C-e>
That said, $ man readline tells you everything you need to customize its behavior and add bindings.
You can use ble.sh. Which is a command line editor written in pure Bash which replaces the default GNU Readline. I like to call it "zsh for bash".
Appart from vim-style navigation it gives you:
Enhanced completion
Syntax highlighting
Other interesting features
After installation don't forget to add (recommended) to your .bashrc:
# at the start of your .bashrc file
[[ $- == *i* ]] && source /usr/share/blesh/ble.sh --noattach
...
#for vim-style mode
set -o vi
...
#at the end of your .bashrc file
[[ ${BLE_VERSION-} ]] && ble-attach
or you can just:
# at the start of your .bashrc file
source /usr/share/blesh/ble.sh
but this may not work as expected - read this.

Busybox: emulate line editing for read shell's built-in

I need to develop a simple text interface for an embedded system with more or less only the Busybox installed on it.
For my purposes the read shell built-in would have sufficed. But the Busybox ash (or any other shell, they use the same code for the built-in) does not support line editing or initial text in the read built-in.
Does anybody knows of a way in Busybox's ash to emulate bash's read -e -i <initial-text> in a shell script?
For readline emulation, there's rlwrap assuming it can be made to fit on the embedded system. Invoke like so: rlwrap ash, which provides command line history and editing.
For read -e -i "foo" bar emulation, try:
read bar ; bar="foo$bar"

Bash usage of vi or emacs

From a programming standpoint, when you set the bash shell to use vi or emacs via
set -o vi
or
set -o emacs
What is actually going on here? I've been reading a book where it claims the bash shell uses either of these editors for the input to the shell itself, but I thought it may have used readline.
Bash is still using readline. Readline uses either emacs or vi mode and setting the mode switches between the various editor modes. You can check the lib/readline folder in the base source code to see the various key bindings.
According to the man page BASH_BUILTINS(1) (on Fedora 8):
set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
... (skipping all the single letter options)
-o option-name
The option-name can be one of the following:
...
emacs Use an emacs-style command line editing interface. This is
enabled by default when the shell is interactive, unless the
shell is started with the --noediting option.
...
vi Use a vi-style command line editing interface.
I interpret that to mean that bash is directly interpreting the commands for line editing. This option simply sets which command set to use. See the man page for readline(3).
It uses the keystrokes that are familiar to users of one of those editors to edit the command line.
Readline is the facility that provides that feature to Bash and other programs.
From man bash:
READLINE
This is the library that handles reading input when using an interac‐
tive shell, unless the --noediting option is given at shell invocation.
Line editing is also used when using the -e option to the read builtin.
By default, the line editing commands are similar to those of emacs. A
vi-style line editing interface is also available. Line editing can be
enabled at any time using the -o emacs or -o vi options to the set
builtin (see SHELL BUILTIN COMMANDS below). To turn off line editing
after the shell is running, use the +o emacs or +o vi options to the
set builtin.
From what I know, readline is what provides the line-editing functionality for bash.
One proviso: when you press v in vi command mode, you get the full blown vi editor to edit your command line.
From man bash:
READLINE
This is the library that handles reading input when using an interactive shell, unless the --noediting option is given at shell invocation. By default, the line editing commands are similar to those of emacs. A vi-style line editing interface is also available. To turn off line editing after the shell is running, use the +o emacs or +o vi options to the set builtin.
When the shell presents you with a prompt (unless you're in non-editing mode), you're already using readline. You'll either be in emacs mode or vi insert mode (which is why you can just use ESC to get back to vi command mode).

Resources