How to override a fish_prompt function from a omf theme - themes

I lost some time on it so I'm creating this Q&A.
I'm using an omf theme and I would like to make a change in the theme prompt. Unfortunately, the change I want to do is not possible by setting the theme config variables.
I tried to edit fish_prompt function using funced fish_prompt; funcsave fish_prompt but if I do so the theme is not loaded anymore so I can't use the functions defined within the theme. The same happens if I just create a fish_prompt function in my config.fish.

tldr
add these lines before you define your own fish_prompt function
source $OMF_PATH/init.fish
# Read current theme
test -f $OMF_CONFIG/theme
and read -l theme < $OMF_CONFIG/theme
or set -l theme default
set -l theme_functions_path {$OMF_CONFIG,$OMF_PATH}/themes*/$theme/functions/
for conf in $theme_functions_path/*.fish
source $conf
end
explanation
When omf is loaded, it add the theme functions files to the $fish_function_path. (source code)
According to fish documentation
When fish needs to load a function, it searches through any directories in the list variable $fish_function_path for a file with a name consisting of the name of the function plus the suffix .fish and loads the first it finds.
What the documentation doesn't explicitly say is if the function is already defined (in config.fish, for example) it will not try to load from $fish_function_path.
So the issue is, when you creates your own fish_prompt function, it shadows the .../<theme>/functions/fish_prompt.fish.
What you need to do to work around it is force loading the theme function file before you redefine it.
For example:
# Read current theme
test -f $OMF_CONFIG/theme
and read -l theme < $OMF_CONFIG/theme
or set -l theme default
set -l theme_functions_path {$OMF_CONFIG,$OMF_PATH}/themes*/$theme/functions/fish_prompt.fish
for conf in $theme_functions_path
source $conf
end
function fish_prompt
# prompt_theme_foo
# prompt_theme_bar
end
Be sure to run it after omf init.fish is loaded.
You can assure by sourcing omf manually source $OMF_PATH/init.fish or be sure omf.fish is in an alphabetical order lesser than your file.

Related

How to override settings in /etc/sysctl.conf CentOS 7?

I was trying to set certain kernel parameters using "/etc/sysctl.conf" file on Cent OS 7.5. I copied "/etc/sysctl.conf" file into "/etc/sysctl.d/sysctl.conf" and updated certain parameters and reloaded settings using "sysctl --system".
But I see parameters inside "/etc/sysctl.conf" overwrites those present inside (/etc/sysctl.d/sysctl.conf) . (I can also see the same when I execute command i.e settings from /etc/sysctl.d/sysctl.conf gets applied first and then settings from "/etc/sysctl.conf" gets applied which causes issue.)
But according to man page as sysctl --system should have ignored settings inside "/etc/sysctl.conf" as I have created file with same name inside "/etc/sysctl.d/sysctl.conf" which gets read first. ( Reference : http://man7.org/linux/man-pages/man8/sysctl.8.html ).
--system
Load settings from all system configuration files. Files are
read from directories in the following list in given order
from top to bottom. ***Once a file of a given filename is
loaded, any file of the same name in subsequent directories is
ignored.***
/run/sysctl.d/*.conf
/etc/sysctl.d/*.conf
/usr/local/lib/sysctl.d/*.conf
/usr/lib/sysctl.d/*.conf
/lib/sysctl.d/*.conf
/etc/sysctl.conf ```
The man page does not agree with the source code sysctl.c. According to the source code of the PreloadSystem() function, it processes the *.conf files in the various sysctl.d search directories (skipping those *.conf filenames that have already been seen, as described in the man page). Then it processes the default /etc/sysctl.conf file if it exists without checking whether the sysctl.conf filename has already been seen.
In summary, the settings in /etc/sysctl.conf cannot be overridden by the *.conf files in /etc/sysctl.d/ and other sysctl.d directories, because the settings in /etc/sysctl.conf are always applied last.

Store an API_KEY in an env var and use in a playlist URL

I use a streaming service (di.fm) that has many channels. Each channel has a playlist I stream from the CLI (using mpv). Each URL in each playlist stores the API KEY.
I want to store the API KEY outside of the individual playlists, so for example, if I change the API KEY, I don't have to change every playlist.
I'm on a Mac.
1) What is the best (safest) place to declare export DI_KEY=""? In .bashrc was my first thought, except I back it up to github. Any other better place to declare the env var that will be created each time I enter bash?
2) In the playlist file, how do I use the $DI_KEY in the URL?
[playlist]
NumberOfEntries=1
File1=http://prem4.di.fm:80/00sclubhits?$DI_KEY
Title1=DI.FM - 00s Club Hits
Length1=0
Version=2
Just referencing it directly doesn't work.
I'm sure this may be answered elsewhere, but in all my searching I couldn't find any helpful answers, particularly to questions 2.
Regarding setting env variables outside of .bashrc, you could create a separate file to define sensitive variables and source this from within your .bashrc.
For example, create a file ~.my-private-variables, add the filename to your .gitignore and add the line export DI_KEY="12345" to this file. Then add the following block in .bashrc:
if [ -f ~/.my-private-variables ]; then
. ~/.my-private-variables
fi
Regarding the playlist file, bash is not running the file, so the environment variable is not expanded.
You could dynamically generate the playlist when bash starts, something like this:
#!/bin/bash
filename=playlist-1.pls
baseurl=http://prem4.di.fm:80
cat << EOF > $filename
[playlist]
NumberOfEntries=1
File1=${baseurl}/00sclubhits?${DI_KEY}
Title1=DI.FM - 00s Club Hits
Length1=0
Version=2
EOF
This will expand the variable and write it to the file, in this case playlist-1.pls in the current working directory. You might add an absolute path to the filename variable that references your playlists directory.
To run this, you could create a script called playlist-generator and source this in .bashrc as described above. You could add as many playlists as you like here.

How to override fish_prompt, keeping the styles from the applied theme?

I installed fish shell, installed few themes. Applied the theme "agnoster", all good is pretty but I want fish_prompt to override the original one and keep the styles in order to show me full path properly. Currently the full path is a shortcut such as Desktop/Abba turns to ~D/Abba and I want to remove the D and will it be ~Desktop/Abba. How can I override function fish_prompt properly so that I am able to call the original previous function from the theme to keep up the styles?
The agnoster theme uses fish's prompt_pwd function to display the pwd.
That shortens each path component to $fish_prompt_pwd_dir_length characters. Set that variable to 0 to inhibit shortening entirely.
Alternatively, you can change the prompt_pwd function however you want it, e.g. via funced prompt_pwd (and funcsave prompt_pwd once you're happy with the result).
I've had a similar issue, but the chosen answer didn't work for me.
In my case, I've had to source all theme files manually before overriding the fish_prompt function.
For example
source $OMF_PATH/init.fish # assure omf is loaded before run the following code
# Read current theme
test -f $OMF_CONFIG/theme
and read -l theme < $OMF_CONFIG/theme
or set -l theme default
set -l theme_functions_path {$OMF_CONFIG,$OMF_PATH}/themes*/$theme/functions/
for conf in $theme_functions_path/*.fish
source $conf
end
function fish_prompt
# prompt_theme_foo
# prompt_theme_bar
end
More details on: https://stackoverflow.com/a/72098697/2180456

sql loader without .dat extension

Oracle's sqlldr defaults to a .dat extension. That I want to override. I don't like to rename the file. When googled get to know few answers to use . like data='fileName.' which is not working. Share your ideas, please.
Error message is fileName.dat is not found.
Sqlloder has default extension for all input files data,log,control...
data= .dat
log= .log
control = .ctl
bad =.bad
PARFILE = .par
But you have to pass filename without apostrophe and dot
sqlloder pass/user#db control=control data=data
sqloader will add extension. control.ctl data.dat
Nevertheless i do not understand why you do not want to specify extension?
You can't, at least in Unix/Linux environments. In Windows you can use the trailing period trick, specifying either INFILE 'filename.' in the control file or DATA=filename. on the command line. WIndows file name handling allows that; you can for instance do DIR filename. at a command prompt and it will list the file with no extension (as will DIR filename). But you can't do that with *nix, from a shell prompt or anywhere else.
You said you don't want to copy or rename the file. Temporarily renaming it might be the simplest solution, but as you may have a reason not to do that even briefly you could instead create a hard or soft link to the file which does have an extension, and use that link as the target instead. You could wrap that in a shell script that takes the file name argument:
# set variable from correct positional parameter; if you pass in the control
# file name or other options, this might not be $1 so adjust as needed
# if the tmeproary file won't be int he same directory, need to be full path
filename=$1
# optionally check file exists, is readable, etc. but overkill for demo
# can also check temporary file does not already exist - stop or remove
# create soft link somewhere it won't impact any other processes
ln -s ${filename} /tmp/${filename##*/}.dat
# run SQL*Loader with soft link as target
sqlldr user/password#db control=file.ctl data=/tmp/${filename##*/}.dat
# clean up
rm -f /tmp/${filename##*/}.dat
You can then call that as:
./scriptfile.sh /path/to/filename
If you can create the link in the same directory then you only need to pass the file, but if it's somewhere else - which may be necessary depending on why renaming isn't an option, and desirable either way - then you need to pass the full path of the data file so the link works. (If the temporary file will be int he same filesystem you could use a hard link, and you wouldn't have to pass the full path then either, but it's still cleaner to do so).
As you haven't shown your current command line options you may have to adjust that to take into account anything else you currently specify there rather than in the control file, particularly which positional argument is actually the data file path.
I have the same issue. I get a monthly download of reference data used in medical application and the 485 downloaded files don't have file extensions (#2gb). Unless I can load without file extensions I have to copy the files with .dat and load from there.

Reduce file path when calling a file from terminal

I'm using Lua in interactive mode on a Mac (thanks to rudix.org).
When I want to load a file I do:
dofile("/my/long/path/to/my/directory/file.lua")
I want to do a different thing, that is:
put all my files in a desktop directory myDirectory;
then call the file from the terminal this way dofile("file.lua");
Is this possible? How?
If the path is fixed, you can just redefine dofile:
local _dofile=dofile
local path=("/my/long/path/to/my/directory/")
function dofile(x)
return _dofile(path..x)
end
You may put this (and other initializations) in a file and set the environment variable LUA_INIT to its location. After this, every invocation of lua will see the version of dofile redefined above and the users will be able to say simply dofile("foo.lua").
Alternatively, you can use require, which looks for modules in a list of paths in package.path or LUA_PATH.

Resources