'Why does ksh's vi-mode in Terminal on macOS "Big Sur" sometimes corrupts the edit line?

I noticed that sometimes when trying to edit a line in the history to re-run a command, that ksh would garble the line and move the cursor up a line. It was really bizarre.

  • first found that it was only long lines where the problem occurred
  • debugging, found that the COLUMNS variable was unset (pretty sure Terminal use to set it)

I could set it by hand to some big number, but then other problems appeared.

I cannot find any way to force Terminal to update the COLUMNS value as the window resizes - how can I do this?



Solution 1:[1]

I just got a new 14" MacBook with the M1 chip and Monterey, and hit the same issue. It doesn't happen on my 2015 MacBook Pro with MacOS 12.4 beta, and after some research I discovered I can get Korn Shell to update the variables on SIGWINCH if I run the binary in x64_64 mode via arch -x86_64 /bin/ksh.

I tried setting a trap on WINCH (window change) that will set the COLUMNS and LINES variables, but while I'm resizing my iTerm window, multiple WINCH signals are sent and thePS1 prompt will be printed each time.

Why it works under x86_64 but not arm64 is beyond me.

I could use this as an excuse to switch to zsh, but my .kshrc file has roots dating back to 1991 and there are enough differences in how command-line editing works that it throws my muscle-memory for a loop.

Solution 2:[2]

This took me forever to track down and fix. ksh will run an .env file before it runs any command, so that's the hook where you can set the value, assuming you can find the value.

After searching high and low, I found that stty will output the current rows and columns, but the values are buried in a big payload of other info. Then I tripped on the resize option, that just outputs the rows and columns as two numbers.

By filtering the output, one can get just the columns number. The solution is to thus add this in a .env file, and make sure ENV is set in your .profile.

COLUMNS=$(stty size | sed -e 's/[0-9]* \([0-9]\)/\1/')

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Trey Valenta
Solution 2