How to change colors programmatically in Konsole based on current directory? - linux

I currently use a color scheme based on which directory that I'm working in. I manually open up a Konsole shell and then cd into a directory and got to Settings and change the color scheme.
What I would like to do is have Konsole automatically set its foreground and background colors based on which directory I'm in. Basically if I'm in any subdirectory below /home/me/src/java then I would like to use text white, background blue, for example. If I'm below /home/me/src/documentation I want text black, background white, for example. I would like the color change to occur automatically, programmatically, when I call the "cd" command.
Is this possible? If so, can you provide me some direction as to how?
The way I see it I will need to be able to do a couple of things:
Be able to detect which Konsole the shell process (bash) is running in.
Be able to tell Konsole, probably via API call, to change the color scheme on the fly.

To get you started, here's a little information about using D-Bus to script Konsole.
You don't say which shell you're using, but if it's Bash you may want to use the $PROMPT_COMMAND variable which holds a command to be executed each time the $PS1 prompt is issued. The Z shell has a similar facility that's probably a bit more powerful (see man zshmisc for chpwd and precmd).
Otherwise, you might be able to use xterm escape sequences.

Context
Actually, Konsole has support for what they profiles. A profile is a group of settings (not only background), which you can manually define under Settings | Manage Profiles and around.
Also, there exists a command line utility called konsoleprofile which allows for programmatic changing of the profiles.
Actual answer
Go to Settings | Edit Current Profile... | Appearance
Define new Color Scheme for each of the directories you want to have special background for, e.g. myprofile1, myprofile2, mystandard
Make sure you can manually call konsoleprofile ColorScheme=myprofile1, konsoleprofile ColorScheme=standard, etc.
Plug in the calls to konsoleprofile into your $PROMPT_COMMAND, e.g. add this to your .bashrc:
PROMPT_COMMAND='[[ "$PWD" = /home/me/src/java* ]] && konsoleprofile ColorScheme=myprofile1 || konsoleprofile ColorScheme=mystandard'";$PROMPT_COMMAND"

Related

Is there a way to change settings (e.g. color scheme) in a running tmux session triggered by a certain shell command (e.g. ssh)?

I just found out about the possibility of hooks in tmux. Since I'm still very new to the command line (and therefore not used to (say need time to) read through all relevant parts of a manpage) I just quickly wanted to ask here, if it is possible to use bash commands to trigger (e.g. when I use ssh, I want to change the color of my status bar). (Although I fear it is not possible).
If not, what could be a way to achieve what I want? Can I make an alias for the command in question and 'reload' a different .tmux.conf file (in a current session)?
Thanks for your help!
Edit:
For example:
I have two versions of a program where I source different environmental variables via aliases (say progVersionA and progVersionB).
When I have a tmux session running, I would like the current 'sourced' environment shown in the status bar (say "progVersionA"). And as soon as I switch to the other program the status bar should read "progVersionB". So, what I want is, that the status bar changes as soon as I run the alias progVersionB.

Can properties like color and font be set on konsole command line?

Hi: I am exploring the possibility of using konsole instead of xterm to run a terminal session, mainly because I believe it might give me a broader set of color options. But I don't know if it's possible to set things like colors and font on the command line when invoking konsole.
What would be great is something like this...
konsole --fg=#ff00ff --bf=#00ff00 -fn= (etc...)
What would be just as good is if I could create and post a profile (as a file) and reference that. Something like...
konsole --profile=/proj/settings/the_konsole.profile
What I can't have is setting colors with a gui tool. The konsole is going to be created for users and they won't have the time/interest/knowledge to play with that stuff.
If the first option is viable, can I specify the color using the hex representation as in the example ?
Thanks
I found that this works...
Create a profile using the gui
-> Settings -> Manage profiles -> New profile -> Etc...
For me, the profile file appeared in... ~/.kde/share/apps/konsole/MyProfileName.profile
Then, just call it out when you invoke konsole...
konsole --profile ~/share/apps/konsole/MyProfileName.profile
Seems to work.
One other thing I discovered...
WHen trying to set the size of the terminal it creates, use --geometry="widthxheight". E.g. --geometry="1000x500"
You also need to use --nofork to get this to work right.
Hope this helps someone.

Is there any way I can change only a specific directory color in linux?

I only need to set a color that will only effect a particular directory not globally.
If you are using Bash in a terminal that supports colors and would like to change the default color for text output to the terminal (not specifically the output of ls) while inside this directory, there is one thing you could do.
The PROMPT_COMMAND variable can be set to execute a command just before printing the prompt. You could use that to check for the current directory and change the terminal color (for instance by assigning the PS1 variable with a prompt that contains non-displayable special codes for selecting a color or echoing said special codes).
PROMPT_COMMAND is documented in the Bash manual: https://www.gnu.org/software/bash/manual/bashref.html
As for how to assign colors, you should look that up if interested.
This solution may not be what you are looking for, will probably have side effects, and generally speaking, I am not sure it will be that useful changing terminal colors depending on the current directory. The usual solution is to have a prompt that shows the current directory path (or at least the last portion of the path).
I use something similar to the above to change text color depending on which machine I am executing Bash on, as I use ssh a lot from one machine to another over several terminal windows, and color (on a black background) is a good way to remember what machine any given window is connected to.

Is there a way to detect the terminal program that someone is using in bash

I'm trying to make a bash script that behaves differently based on the terminal program that someone is using (Putty, mobaxterm, etc). Is there any way to retrieve this kind of information from a bash script?
I was searching around online but I was not able to find anything (or I'm just wording it incorrectly, which could be a distinct possibility).
thank you
You need to understand that these are terminal emulators. There is a simple, crude identification function for (most?) modern line terminals (now that's an oxymoron!) but it will return something like vt102 or xterm i.e. whatever the emulator is emulating; not the identity of the program performing this emulation. Incidentally, this is usually used when the session is initiated, and reflected in the value of the $TERM environment variable.
The common way to do this is the environment variable TERM. Try
echo $TERM
That should output the terminal emulator's type, indicating its capabilities. Often, though not always, the value of TERM will be the name of the terminal emulator. For example, xterm may set TERM to xterm, or to xterm-color, depending on configuration.
Note that the user can change this variable, so it may contain something completely different.
That said, if you want to do fancy things with the terminal from a script, you don't need to build support for different terminals by hand. There are various libraries that offer all the usual functions (clear terminal, resize window, change font etc.). The most popular one is terminfo; there are various packages that build on terminfo.

How can I change the color of my prompt in zsh (different from normal text)?

To recognize better the start and the end of output on a commandline, I want to change the color of my prompt, so that it is visibly different from the programs output. As I use zsh, can anyone give me a hint?
Put this in ~/.zshrc:
autoload -U colors && colors
PS1="%{$fg[red]%}%n%{$reset_color%}#%{$fg[blue]%}%m %{$fg[yellow]%}%~ %{$reset_color%}%% "
Supported Colors:
red, blue, green, cyan, yellow, magenta, black, & white (from this answer) although different computers may have different valid options.
Surround color codes (and any other non-printable chars) with %{....%}. This is for the text wrapping to work correctly.
Additionally, here is how you can get this to work with the directory-trimming from here.
PS1="%{$fg[red]%}%n%{$reset_color%}#%{$fg[blue]%}%m %{$fg[yellow]%}%(5~|%-1~/.../%3~|%4~) %{$reset_color%}%% "
Zsh comes with colored prompts builtin. Try
autoload -U promptinit && promptinit
and then prompt -l lists available prompts, -p fire previews the "fire" prompt, -s fire sets it.
When you are ready to add a prompt add something like this below the autoload line above:
prompt fade red
Here's an example of how to set a red prompt:
PS1=$'\e[0;31m$ \e[0m'
The magic is the \e[0;31m (turn on red foreground) and \e[0m (turn off character attributes). These are called escape sequences. Different escape sequences give you different results, from absolute cursor positioning, to color, to being able to change the title bar of your window, and so on.
For more on escape sequences, see the wikipedia entry on ANSI escape codes
The answer by Bryan Oakley above has a glitch as it has already been pointed out and the solution offered by Andrew Marshall though it does not carry the glitch, nevertheless it does not make it obvious for too much customization on the colors used.
As macOS Catalina asks for zsh to be the default shell from now on, I think several more people may want to customize their prompt and might be coming here for an answer. So, I thought I would try to give a broader summary and touch upon other very closely-related notions that allow more customization.
3-Digit Codes for Various Colors.
First of all, here we can find 3-digit codes for various colors: https://unix.stackexchange.com/a/124409/194343.
For example, 214 is some kind of orange color.
Foreground and Background.
The other key information is that for Foreground and bacKground colors one can define what they want with F and K respectively. Source is zsh manual on visual effects: http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html#Visual-effects
So, for example, the following two commands
autoload -U colors && colors
export PS1="%F{214}%K{000}%m%F{015}%K{000}:%F{039}%K{000}%~%F{015}%K{000}\$ "
present the hostname in orange with black background, followed by a colon in white with black background, followed by the current working directory in bright blue with black background, followed by the dollar sign in white with black background.
More related information is found below.
Prompt information on the right-hand side. For example, adding a timestamp. See https://superuser.com/a/1251045/290299. Of course, this can be color-coded, for example with some light blue/purple-ish color, like this:
RPROMPT="%F{111}%K{000}[%D{%f/%m/%y}|%#]"
Colors for ls. After reading the manual for ls, one for example can activate the colors for ls using the following two commands:
export CLICOLOR=1
export LSCOLORS=gafacadabaegedabagacad
Finally, as a last remark that I have not tested as I am happy with my configuration, another avenue might be for someone to install the port coreutils from MacPorts and then use gdircolors (source: https://unix.stackexchange.com/a/174596/194343). (I may edit this last part in the future as all the above are related pieces that make every-day life much more fun and easier to cope with.)
I don't think the autoload -U colors && colors is needed anymore and one can simply do:
PS1="%{%F{red}%}%n%{%f%}#%{%F{blue}%}%m %{%F{yellow}%}%~ %{$%f%}%% "
to achieve the same result as FireDude's answer. See the ZSH documentation for more info.
Try my favorite:
put in
~/.zshrc
this line:
PROMPT='%F{240}%n%F{red}#%F{green}%m:%F{141}%d$ %F{reset}'
don't forget
source ~/.zshrc
to test the changes
you can change the colors/color codes, of course :-)
In order to not waste space in the terminal with special characters to pieces of information, you can differentiate information using multiple colors.
Eg. in order to get this desired effect:
You can do the following to your prompt:
PROMPT='%F{magenta}${PWD/#$HOME/~} %F{green}${vcs_info_msg_0_} %F{cyan}$%F{reset_color} '
The way it works is every time you set a color using $F{myColor} the color from that point onward will stick to that. It's important to add in %{reset_color} at the end so that the input text goes back to the original color (or you could set it to something else if you'd like).
I have found that, with zsh5 (the default one on Debian Jessie), all those solutions works:
$'\e[00m
$fg[white]
$fg{white}
Now, they have a problem: they will move the cursor, resulting in ugly decal when tabbing (for auto-completion). The solution is simply to surround the escape sequences with %{FOOBAR%}. Took me a while to figure this.
For 2nd and 3rd solutions loading colors module is mandatory.
To keep the 1st solution readable, just define variables for the colors you use.
Debian/Ubuntu/Raspberry Pi OS style bash prompt:
autoload -U colors && colors
PS1="%B%F{034}%n#%m%f%b:%B%F{019}%~ %#%f%b "
Not entirely sure if autoload -U colors && colors is necessary but I did need it when I was using $fg[...] instead of %F{...}.
In my example;
%F(%f) starts(stops) foreground color - I've used 256COLOR values but you could also use hex for example, I've used normal green %F{034} but %F{#00aa00} works too
%B(%b) starts(stops) bold
%n $USERNAME
%m short machine name
%~ logged in/working directory with ~ if in home directory
%# display % if normal user or # if su
Edit: Tested on macOS Big Sur, Monterey and Ventura. Unsure of earlier zsh versions but Ventura 13.0 is zsh 5.8.1 (x86_64-apple-darwin22.0)
To get a prompt with the color depending on the last command’s exit status, you could use this:
PS1='%(?.%F{green}.%F{red})%n#%m:%~%# %f'
Just add this line to your ~/.zshrc.
The documentation lists possible placeholders.
To complement all of the above answers another convenient trick is to place the coloured prompt settings into a zsh function. There you may define local variables to alias longer commands, e.g. rc=$reset_color or define your own colour variables. Don't forget to place it into your .zshrc file and call the function you have defined:
# Coloured prompt
autoload -U colors && colors
function myprompt {
local rc=$reset_color
export PS1="%F{cyan}%n%{$rc%}#%F{green}%m%{$rc%}:%F{magenta}%~%{$rc%}%# "
}
myprompt
man zshall and search for PROMPT EXPANSION
After reading the existing answers here, several of them are conflicting. I've tried the various approaches on systems running zsh 4.2 and 5+ and found that the reason these answers are conflicting is that they do not say which version of ZSH they are targeted at. Different versions use different syntax for this and some of them require various autoloads.
So, the best bet is probably to man zshall and search for PROMPT EXPANSION to find out all the rules for your particular installation of zsh. Note in the comments, things like "I use Ubuntu 11.04 or 10.4 or OSX" Are not very meaningful as it's unclear which version of ZSH you are using. Ubuntu 11.04 does not imply a newer version of ZSH than ubuntu 10.04. There may be any number of reasons that an older version was installed. For that matter a newer version of ZSH does not imply which syntax to use without knowing which version of ZSH it is.

Resources