ksh - Display Current Mode - shell

Is there any way to have ksh display the current typing mode at the bottom of the window like vim; like "Insert", "Command", "Visual", etc? Unfortunately, I am having a lot of trouble remembering which mode I'm in and find the shell unintuitive (at least until I get used to all the commands). I consistantly hit the wrong key in command mode and have difficulty figuring out how to get back to proper typing (sometimes it lets me type but not delete part of the line and I don't know why).
I am required to use ksh for work and am heavily restricted in what I can download and install, but I need to figure this out. Hopefully there is something I can do with a profile or script along these lines to help ease the transistion. Also, this is HP-Unix, in case that affects anything.

This set -o alone command will show if emacs is defined to on
$ set -o|grep emacs
emacs on

Related

How can I make my terminal text rainbow colored upon every boot up? (with lolcat)

I've been wondering how I could do some of these cool customization options for the terminal on a Mac and I came across lolcat.
However, I can't seem to find an answer as to how to add this into my bashrc (FYI: I'm using zsh now just in case that makes a difference as to which file to add my customizations in) I have tried what many others have suggested, which was just typing zsh | lolcat into the terminal to get rainbow output in the current session, but I was wondering how I can have this every time I start a terminal session.
Also, I'm not sure if this is a bug or if there's something wrong with my terminal settings, but when I use a command with lolcat, I get an output like this:
karenlee#Karens-MBP ~ % Documents
Downloads
Library
Movies
Music
Pictures
Postman
Public
38;5;48m
karenlee#Karens-MBP ~ % 38;5;48m
The colors look right, but as you can see, when I type the ls command on the command line, it disappears and the output also gets messy. It also seems like there's extra lines of 38;5;48m which are appearing. And it also seemed like many of the gems that are installed with lolcat have deprecated; is there another alternative to lolcat that plays nicely with macOS Catalina?
I made a shell extension for the world's fastest website generator that I make called Nift. It has an easter egg where you can turn on lolcat output for most things with lolcat.on (after starting the shell with eg. nift sh). You will even get rainbow output when pressing tab to get possible completion options, I doubt you get that with any other suggested solutions.
The shell extension is for f++ which is the in-built scripting language, which has these functions and these types available. But anything it doesn't recognise is run as a system call using the (probably primary/default) shell on your machine (hence calling it a shell extension in REPL shell mode).
Nift will look for a version of lolcat installed on your machine and otherwise use an in-built version of it which should be the world's fastest (it's near identical to my c++ implementation lolcat-cc which is the world's fastest). I highly recommend installing lolcat-cc (or another version of lolcat) on top of Nift though as otherwise you are frequently running the ~5mb Nift binary for basically all system calls, instead of a <1mb binary for lolcat.
f++ is somewhat of an interesting scripting language as well. Take this script for example which creates and deletes 100k empty text files. On my machine this runs in ~3.5 seconds whereas this Bash script doing essentially the same thing takes more like 3 minutes!! Some of the cool things you might already notice from that f++ script is you can expand variables inside strings, you can define variables with types, you can expand variables in to multiple parameters with function calls, you can have LOTS more than 10k input parameters for function calls (should be able to have millions!).
You can find some more information about the Nift REPLs (including shortcuts for different platforms) here.
If you need to define shell variables (not through f++ but the underlying shell) then you will need to do blocks of code using the sys/system function. You can also do blocks of code for Lua(JIT) and ExprTk similarly as they are both embedded in to Nift. You can use both Lua and ExprTk with accessing/modifying f++ variables as well..
So to get this shell (extension). Install Nift through a package manager or clone, make and install off GitHub. Enter nift sh in to your terminal to start the Nift f++ shell extension, then enter lolcat.on to turn on rainbow output.

Refreshing Bash prompt after invocation of a readline bound command

My shell is GNU Bash 4.3.11, and I currently have M-h bound to cd .. by calling the builtin
bind -x '"\eh": "cd .."'
This gives me a nifty way to navigate up the directory tree, as I can repeatedly hit M-h instead of the incredibly time-consuming cd ... It has the downside, however, either of not resetting my $PS1 or of not redrawing my prompt, so I lose the context of my current working directory until I enter a new command.
One alternative I'm aware of is to put a macro like
"\eh": "\C-a\C-kcd ..\C-m"
in my .inputrc directly. This, however, has the downside of not only losing the context of any existing command I'm typing in (which I think can probably be worked around) but also of printing out cd .. (which I don't think can be).
My desired behavior is to be able to be in a directory ~/one/two with prompt ~/one/two$; hit M-h; and then be in ~/one and have the prompt be ~/one$, ideally keeping any command I had initially. How can I achieve this?
Figured this out.
# maintain state
bind -x '"\200": TEMP_LINE=$READLINE_LINE; TEMP_POINT=$READLINE_POINT'
bind -x '"\201": READLINE_LINE=$TEMP_LINE; READLINE_POINT=$TEMP_POINT; unset TEMP_POINT; unset TEMP_LINE'
# "cd .." use case.
bind -x '"\206": "cd .."'
bind '"\eh":"\200\C-a\C-k\206\C-m\201"'
I'm quite late to that party - and came here looking for that answer also. First of all: As you were the only one providing information on this: thanks for not letting it come to this: https://xkcd.com/979/ ;) instead you pointed me to the on corner in that fractal that seems to hold a solution.
This approach, in my opinion backed up by hours of trying, is the only one where you can a) replace content on the line, and b) execute bash code. Let me offer up some more suggestions to a specific problem:
If you are trying to have it both ways: insert something on the command line, or executing code, things can get very tricky. for both, there exist bindings, and I let the reader figure out things with help bind. But in the case you e.g. have FZF produce some directory as output, and you'd either cd to it, or have it pasted into your command -- depending on the keystroke done in FZF -- things will get near impossible. you'll face either the not-updated-promt problem, or not be able to execute the cd command in the top shell (where it has effect).
Your solution would be a multiplexing -x binding, inspecting the output for "macros" (get extracted and eval'd) or the default pass-through (manipulating READLINE_LINE/POINT).
Because the solution has some enormity, and the audience may be limited (closed answer...), I'll leave it at a haphazard gist where I pasted my code which works now. To make up for the brevity and uncommented-ness, I welcome any questions in comment or elsewhere. Hope someone may be pointed in the right direction.
- The code related to this question starts in function bindInsertEvalWithMacrosVi
- It is designed for Vi keybindings but the same principles apply for normal readline mode
- It depends on some \C-x\C-... combinations to do redrawing in places that are not related to this post.
https://gist.github.com/simlei/032470cfcd23641987f97a96749128d7

modifying the bash prompt on mac

On my bash prompt, I would like to see just the name of the current directory followed by "$" in different colours.
So I used this code but when I have a long typed command, I see the cursor in different place than where the typing is taking place. How can this "hard to describe" problem be fixed? Thanks
PS1='\[\e[0;36m\]\W\[\e[m\]\[\e[1;31m\]\$\[\e[m\]'
Use a carriage-return after outputting the current directory, I've done this for years and it works a treat, something like:
if [ "$PS1" ]; then
PS1="\[\e[0;36m\]\W\n\[\e[m\]\[\e[1;31m\]\$\[\e[m\]"
fi
You always have your current directory (no matter how long) on top of your $ prompt.
I put other info up there as well like username, machine name and exact time and date. I colour them differently so they really stand out. Helps if you have multiple sessions going on, on different machines with or without root(!) privileges (have to be root when deploying a complete rebuild). And has saved the day many times when I need to know when I did something or other (ok, it's when that task ended - but still helps).
But most of all, it's great to know your current directory by simply looking at your command line prompt :) )
Don't know how other people work efficiently without it!

How to test that `clear` command is working correctly in BASH?

Now i try find the way to prove that a clear command is working correctly on my own REPL
Example
$ cd ~
$ pwd
/home/user
$ echo "hello"
hello
then type clear
$
but sometime some unexpected behavior is occurred after using a clear command
e.g.
[one blank line here]
$
A one blank line after using clear command is undesirable behavior and I hope this kind of bug can be detected automatically via a unit test. If you have any idea to prove that clear command is working correctly please purpose.
There is no easy way to do this. "clear" sends a sequence of bytes that tells the terminal to clear its screen. Different terminals use different sequences. There is a table called "termcap" (terminal capabilities) that lists the difference sequences for different types of terminals. The environment variable "TERM" should be set to the type of terminal you are using.
TERM is usually set to "xterm", "xterm-color", "vt100", or related value. On my Mac OS X Terminal it is set to "xterm-256color".
TERM should be set automatically for you. If your OS is set up properly you shouldn't have to set it yourself. However in the old days you had to set it manually. Therefore you'll find a lot of old .profile/.bashrc/.cshrc files that set it. Check to see if that is happening and remove that (comment it out) to see what is automatically set.
Your question boils down to "how can I tell if my TERM variable is set right?" and the answer is: You can't. You could do things like clear the screen then ask the user if they saw their screen clear. However, if programs did that on start-up, it would be very annoying.

How to quickly scroll to the latest / end of command history in bash?

Lots of times I'll use Ctrl-R for reverse search and mistype some letter. Bash jumps up hundreds of lines and I'm in the middle of commands I was using a week ago.
Is there a shortcut for jumping back down to the lastest commands I had typed?
Edit: after testing it out on a CentOS server and Mac OS X, it looks like this only happening on OS X.
I've struggled with this same issue.
You can solve this by aborting with ctrl-c. Whether you're in the middle of a reverse search or scrolling through history with the arrows, aborting returns you to a prompt with the history scroll just after the last command.
UPDATE
Here's a nice trick I just learned. Bash and many other programs use Readline under the hood for command-line interpretation. Key bindings for Readline can be configured in a .inputrc file or with the bind command. The bindings can make use of a few functions provided by Readline. For example, I use Bash in vi mode but I still like to use Emacs-style ctrl-A so I have this line in my .bashrc file:
bind '\C-a:beginning-of-line'
To list all the available Readline functions:
bind -l
Among the functions is end-of-history. The function does like its name suggests. The difference between this approach and just using the abort command is that this keeps you on the same prompt.
If using libreadline, Alt-> (or Meta->). More info on Readline shortcuts or search for Commands for Manipulating the History in the man page.
On Mac, try command + .
It works for me.
I was trying alt+. and alt+shift+. , neither works for me. And then found command + . actually works
Maybe not exactly what you want, but you can fix your mistyped character(s) by using backspace when you're in the CTRL-r (reverse-i-search) mode.
You may wan to try "suggest box"-like history HSTR. It reads the bash history and allows quick navigation and filtering - you can see the context of similar history entries. Once you select a history entry it can be edited on the command line.
In Zsh with emacs binding set the actual default key sequence is ^[> binded to end-of-buffer-or-history command rather than command-. suggested above (or end-of-history depending on effect you want to achieve)
Cmd-. produces in Apple Terminal the similar or the same key sequence as Ctrl-C, which can be confirmed by running something useless and long, e.g. find . >/dev/null 2>&1 and pressing one and then other keys on keyboard.
Ctrl-C forces input to be ended and reset. and history scroll is just a side effect for it.

Resources