How can I bind a function key to emit a color code? - bash

I'm making a terminal recording and I would like to change the terminal foreground color to emphasize certain parts (such as certain command line arguments) in the recording.
How can I map a function key to emit a color code in bash/readline?
I can bind to other things like the arrow keys using bind '"\e[21~":"\e[A"', so I think doing something like bind '"\e[21~":"\e[[31m"' should emit a color code and change the fg color.
It doesn't. How do I make this work?

If you bind a key to a string like \e[A then this key emits this string which in turn is again parsed by the readline library and interpreted (in this case to mean "up" which is then pointing to the function previous-history). The string is never printed to the terminal.
So if you want to print something, you need to bind a key to a function which prints something arbitrary (your ANSI color escape sequence). I'm not aware of such a readline function because it doesn't make much sense if you think it through. The problem is that readline has no notion (no internal model) of colored characters. Readline is for raw characters only, without character styles. Switching the color, entering some visible characters, then using cursor keys to edit already typed (maybe colored, maybe standard) characters -- stuff like this will lead to redraws of the complete line. In that process the colors will be eradicated quickly (because readline doesn't really know about them).
So I guess what you want just isn't possible. It is a feature not supported by readline and which you cannot simply add to it (correctly) from the outside without breaking things.

Related

terminal calendar khal: Highlight current date when spawning with naughty.notify in awesome wm

I am trying to spawn khal, a terminal calendar, when mouse pressing the default textclock widget in awesome wm.
local cal_notification
mytextclock:connect_signal("button::release",
function()
if cal_notification == nil then
awful.spawn.easy_async(noisy,
function(stdout, stderr, reason, exit_code)
cal_notification = naughty.notify{
text = stdout,
width = auto,
destroy = function() cal_notification = nil end
}
end
)
else
naughty.destroy(cal_notification)
end
end)
Unfortunately on execution, all syntax highlighting of khal is gone.
Does anyone have an idea how to spawn a notification without losing the 'look'?
Edit:
This occurs probably with any other terminal calendar, for example with cal, I think.
With grep --color -EC6 "$(date +%e)" it still doesnt output color.
With a forced --color statement of khal it outputs 001b 1m before every highlighted character.
CLI applications like khal use so-called ASCII escape codes to encode the coloured highlighting. Parts of those is what you saw with "outputs 001b 1m before every highlighted character".
There are more characters within those sequences than what you pasted here, but those are likely swallowed by Lua's string handling or awesome's rendering.
The problem here is the fact that this way of highlighting text using ASCII escape codes is something that's specific to terminals and terminal emulators. Other applications do not use or implement them.
For awesome specifically, text markup is done through Pango Markup. So for your notifications to retain the highlighting created by khal, you will need to create a conversion layer that transforms the ASCII escape codes into Pango markup.
An additional challenge is the fact that colours in terminals use a theme-based system. The terminal is configured with a certain set of colours, and the escape codes merely index into that list. They don't hold any actual colour information themselves. However, for Pango, you need to specify the actual colour value in the markup.

Change Color of Text Being Currently Used (Terminal - OSX)

For reference purposes: I am using a Macbook Pro Retina (2014) and all software is up to date as of the time I am posting this question. (Using OSX 10.10.2 Yosemite)
I have been struggling for the past few days as I attempted to customized the Terminal window. Everything was going fine... until I decided I only wanted to change the color for the text that you are currently typing (text input) which will then be executed.
I have no problems getting into my .bash_profile and adjusting anything. I simply cannot seem to grasp the color concept well enough such that it only does this one thing for me. Currently my .bash_profile looks like this:
export PS1="\n\n\njboned$ "
export PATH="/usr/local/mysql/bin:$PATH"
export CLICOLOR=1
export LSCOLORS=ExFxCxDxBxegedabagacad
Any assistance would be greatly appreciated. As a sidenote: I understand the 8-bit snippets used to represent the individual colors, however it seems I cannot figure out how to use them to address only the text input only.
To do what you are asking, these steps would be needed:
at the end of the prompt, turn on the text color which you want to show
when you press return (to complete editing) turn the text-color off.
bash does not reset attributes while you edit, so the color "should" work — while editing. As you edit, bash is likely to use escape sequences which clear the current line (which may fill it with whatever background color you have selected).
The real problem is how to reset the colors when you press Enter. That does not appear to have a straightforward solution: I do not see a way to rebind the Enter key to add features—no distinction is made between levels of interpretation, and you may not find it possible to enhance the Enter key. The key binding feature in bash talks mainly to the readline library; leftovers are sent to bash. In a binding you may be able to do these things:
send the name of a macro to bash, or a full echo command which resets colors (since readline has no echo of its own, it seems)
the Enter key (i.e., ^M), and
to readline directly, the accept-line function
Alternatively, what you could do is bind another key, say control/L to do the bash accept-line function as well as resetting color. Here are a couple of links which you would find useful to investigate how to do this:
how to bind the 'Enter key'
Complex keybinding in bash
In bash, how do I bind a function key to a command?
Smart preparsing with the bash shell

how to get current terminal color pair in bash

I would like to query and store the current terminal color pair in BASH e.g.:
#!/bin/bash
#some ANSI colour escape sequences
red="\033[0;31m"
grn="\033[0;32m"
blu="\033[0;34m"
def="\033[0;00m" # default
echo -e "Change to ${red} red to ${def} default to ${blu} blue."
# now store the current color (which happens to be blue) e.g.:
cur=????
echo -e "Change to ${grn} green and back to what I had before ${cur}"
echo -e "This would be in blue if variable cur contained e.g.: 0;34m."
echo -e "Back to default${def}"
exit 0
The answer that eludes me is how to capture the current color
cur=????
The question was about the current color, not the cursor position.
Both are "nonstandard" (though the latter, cursor position report is implemented by anything which has a valid claim to "VT100 emulator").
However, xterm implements a set of escape sequences referred to as dynamic colors, which predate the ANSI color functionality. Those set the working colors including text foreground and background. I modified this in 2002 to allow an application to send the sequence with a "?" rather than a color to tell xterm to return the color value, e.g.,
OSC 1 1 ? ST
using the notation given in XTerm Control Sequences
You can't; there is no standard control sequence to report the current cursor attributes.
What does exist, however, is a sequence to save and restore the current cursor position and attributes:
\e7 (DECSC) will save the cursor position and attributes.
\e8 (DECRC) will restore the saved cursor position and attributes.
There is no standard way to restore only the cursor attributes; however, as rici mentioned, you can get a report of the current position using \e[6n (DSR), then use the response to manually "un-restore" the cursor position after restoring its position and attributes.
Again, though, it's probably easier (and better) to just keep track of the colors in your application, rather than making the terminal responsible for that.
It's important to understand that the terminal state has nothing to do with bash. Bash doesn't care. It simply reads from stdin and writes to stdout and stderr. (See Note 1)
All terminal effects are implemented by the terminal emulator you happen to be using, of which there are many. In a graphical environment, you might be using, for example, xterm or konsole. You'll need to search the documentation for those emulators for specific terminal control codes which they interpret.
As far as I know, there is no standard code to get a report of the current terminal state, other than the cursor position (ESC[6n).
So your best bet is to remember the changes you made when you make them.
You can find a list of the standard codes implemented by the Linux console using man console_codes (although few people use the Linux console these days); most of those are also interpreted by xterm and other graphical consoles. There's an list of xterm sequences in Thomas Dickey's xterm site; it's a more or less de facto standard for terminal emulators but, as I said, you'll need to search in each emulator's documentation for idiosyncratic control sequences.
Notes
In interactive mode, bash uses a library called readline to help it handle some terminal effects. In particular, readline tries to maintain the current console cursor position, although it is easy to fool it. In PS1 you need to surround console control sequences with \[ and \] precisely because readline does not know that they are control sequences.
What I understood, is that u are asking to to get the default profile color of the user, of which u have change color of!
Eg: User is using 'Bright Green font color on Black background', you change it to 'Red font color on White background'. Now how to get/know the default colors and set them back to it!
You can use the sequence \033[0m in bash [also for command prompt (batch scripting) / powershell (ps scripting)]

Lightweight event wrapper for the terminal

I believe this is the realm of the ncurses library. I'm trying to avoid having to get down and dirty with it though.
I'm looking for a program that I can configure to run a command while performing terminal mouse reporting translation to keypresses.
This is for use with pagers like less.
For example the MouseTerm SIMBL plugin for Terminal.app does exactly this.
But iTerm2 does not. And I want it.
I think the answer may be as simple as directly remapping the codes.
It looks like there are escape codes to switch the terminal into and out of mouse-listening mode, and mouse click escape codes actually seem to include the character coordinates. I can look at them with Ctrl+V inside of Vim because I have told vim to turn on the mouse.
It looks like this:
Note ^[ denotes escape (you can type escape by typing ctrl+[)
left click: ^[[M !!
right click: ^[[M"!!
middle click: ^[[M!!!
scroll up: ^[[M`!!
scroll down: ^[[Ma!!
So that does match up with the mouse wheel button codes being 64 more than the mouse button ones according to documentation (I like this page).
Now that I'm armed with the knowledge of what codes I need to map to what I just need to find out how to get a layer that lets me filter the input.
This has apparently led me to an epiphany. I simply need a simple non-line-buffering program that listens for mouse escape codes and replaces them with key codes. Surely Perl Term::ReadKey will let me set raw mode and do this nearly trivial task.
This stuff is difficult. I've been making do by configuring Tmux to handle things.

How Do ncurses et. al. Work?

There are several libraries like ncurses that assist in making command-line GUIs.
Simply put, how do they work?
My first thought was that ncurses intercepts all keyboard input, and draws each "frame" by outputting it line-by-line normally. Closer inspection, however, reveals that each new frame overwrites the previous one. How does it modify lines that have already been outputted? Furthermore, how does it handle color?
EDIT: The same question applies to anything with a "fancy" interface, like vim and emacs.
Text terminals have command sequences that do things like move the cursor to a particular position on the screen, insert characters, delete lines etc.
Each terminal type is different and has its own set of command sequences. ncurses has a databse (see terminfo for details)
Internally ncurses maintains 2 views of the screen: the current contents and what the screen should look like after the current pending changes are applied. Once the program requests a screen redraw, ncurses calculates an efficient way to update the screen to look like the desired view. The exact characters/command sequences output depend on what terminal type is in use.
curses (and ncurses, too, I think) works by moving the cursor around on the screen. There are control sequences to do such things. Take a look at the code again and you'll see them. These sequences are not ASCII control characters, they are strings starting with (umm...) ESC, maybe. Have a look here for a higher-level explanation.

Resources