added PWDLEN enviorment variable to configure PWD in prompt PWD will also now replace $HOME with ~ when printing error handing improved $SHELL must match to *bash in order to run
sophuwu sophie@sophuwu.com
Tue, 01 Jul 2025 08:24:19 +0200
6 files changed,
108 insertions(+),
49 deletions(-)
M
releaser/bash-rb-ps1.1
→
releaser/bash-rb-ps1.1
@@ -19,6 +19,13 @@ .B view
Print the PS1 with xterm color codes, without PS1 syntax. This is used to preview the prompt before enabling it. .SH ENVIRONMENT .TP +.B PWDLEN +sets the number of parents shown in PWD. + 0 will show the full path. + 1 will show only the current directory name. + 2 will show the current directory and its parent, and so on. + If unset, it defaults to 2. +.TP .B IPCOLOR changes the color palette used for the IP address. If set to `alt`, it uses an alternative color palette.
M
src/common.cpp
→
src/common.cpp
@@ -6,36 +6,60 @@ paStr DBG = {"\033[","m"};
paStr* esc = &PRT; str wrap(str s) {return esc->s + s + esc->e;} -str docmd(const char* inputted) { - FILE* file = popen(inputted, "r"); +void exportenv(str k, str v) {printf("export %s=\"%s\"\n", k.c_str(), v.c_str());} + +int strEnv(str &dst, cstr env) { + cstr val = getenv(env); + if (val == NULL) return 0; + str out = ""; + for (int i = 0; i < 1024 && val[i] != '\0' && val[i] != '\n'; i++) { + out += val[i]; + } + if (out.empty()) return 0; + dst = out; + return 1; +} + +str docmd(str inp) { char buff[1024]; - int n = fread(buff, 1, sizeof(buff), file); - pclose(file); + int n = 0; + inp += " 2>/dev/null"; // ignore errors + try { + FILE *file = popen(inp.c_str(), "r"); + n = fread(buff, 1, sizeof(buff), file); + pclose(file); + } catch (std::exception &e) { + return str(""); + } str r = std::string(buff, n); if (r.back() == '\n') r.pop_back(); return r; } -str envorcmd(str env, str cmd) { +str envorcmd(cstr env,cstr cmd) { str ret = ""; - try { ret = std::string(getenv(env.c_str())); } - catch (std::exception e) { ret = docmd(cmd.c_str()); } + try { ret = std::string(getenv(env)); } + catch (std::exception e) { ret = docmd(cmd); } return ret; } int atoi(int &n, const char *c, int i=0){ n=0; - for (; c[i] >= '0' && c[i] <= '9'; i++) n = n*10 + (int)c[i] - (int)'0'; + for (; c[i] >= '0' && c[i] <= '9'; i++) n = n*10 + (int)(c[i] - '0'); return i; } +int intenv(cstr env) { + int n = 0; + intenv(n, env); + return n; +} -int intenv(const char* env) { - int n=0; +int intenv(int &n, cstr env) { const char* val = getenv(env); - if (val == NULL) return n; + if (val == NULL || val[0] == '\0') return 0; atoi(n, val); - return n; + return 1; } std::vector<str> split(str s, char delim) {@@ -43,6 +67,7 @@ std::vector<str> ret;
str temp = ""; for (int i = 0; i < s.length(); i++) { if (s[i] == delim) { + if (temp == "") continue; ret.push_back(temp); temp = ""; } else temp += s[i];@@ -67,6 +92,6 @@ str ret = "48;5;";
ret += std::to_string(top); ret += ";38;5;" + std::to_string(bot); ret = wrap(ret); - ret+="▄"; // "▌" "▀" "▄" "▌" + ret+= "▌"; // "▄" "█ " return ret+wrap("0"); }
M
src/common.hpp
→
src/common.hpp
@@ -11,6 +11,7 @@ #include <cmath> // for sin
#include <vector> #include <string> typedef std::string str; +typedef const char* cstr; struct paStr {str s, e;}; extern paStr PRT;@@ -18,10 +19,13 @@ extern paStr DBG;
extern paStr* esc; extern str wrap(str s); -extern str docmd(const char* inputted); -extern str envorcmd(str env, str cmd); +extern void exportenv(str k, str v); +extern int strEnv(str &dst, cstr env); +extern str docmd(str inp); +extern str envorcmd(cstr env, cstr cmd); extern int atoi(int &n, const char *c, int i); -extern int intenv(const char* env); +extern int intenv(int &n, cstr env); +extern int intenv(cstr env); extern std::vector<str> split(str s, char delim); extern int int2col(int n);
M
src/ip.hpp
→
src/ip.hpp
@@ -10,6 +10,8 @@
struct IP { int values[4]; int fromString(str s) { + // anything shorter than 0.0.0.0 cannot be valid + if (s.length() < 7) return 0; int pos = 0; int c = 0; for (int i=0;i<4;i++) {@@ -30,20 +32,23 @@ if (c == 0) return 0;
return 1; } int fromEnv() { - const char * env = getenv("IPStr"); - if (env != NULL) return fromString(std::string(env)); + str v; + if (strEnv(v, "IPStr")) return fromString(v); return 0; } int fromCmd() { - str s; - const char * env = getenv("IPCmd"); - if (env != NULL && fromString(docmd(env).c_str())) return 1; - return fromString(docmd("hostname -i").c_str()); + str s = "hostname -I"; + strEnv(s, "IPCmd"); + if (fromString(docmd(s.c_str()))) exportenv("IPStr", toString()); + return fromString(s); } int get() { - int ok = fromEnv(); - if (!ok)ok = fromCmd(); - return ok; + if (fromEnv()) return 1; + if (fromCmd()) { + exportenv("IPStr", toString()); + return 1; + } + return 0; } str toColor() { str ret = "";
M
src/prompt.cpp
→
src/prompt.cpp
@@ -8,9 +8,6 @@ #include "common.hpp"
#include "ip.hpp" #include "rainbow.hpp" - -void exportenv(str k, str v) {printf("export %s=\"%s\"\n", k.c_str(), v.c_str());} - int randint(int n) { if (n<=0) return 0; FILE *f = fopen("/dev/urandom", "r");@@ -75,16 +72,48 @@ for(int i = 0; i < abs(wave(wavefactor)); i++)r.next();
return r; } -str getpwd() { - str pwd; - try { pwd = std::string(getenv("PWD")); } - catch (std::exception e) { pwd = ""; } - if (pwd.back()=='\n')pwd.pop_back(); - return pwd; +void getpwd(escape &esc) { + str pwd, home; + if (!strEnv(pwd, "PWD")) return; + strEnv(home, "HOME"); + int inHome = 0; + if (!home.empty() && pwd.length() >= home.length() && pwd.substr(0, home.length()) == home) { + pwd = pwd.substr(home.length()); + inHome = 1; + } + std::vector<str> parts = split(pwd, '/'); + + + int n = 2; + int siz = parts.size(); + intenv(n, "PWDLEN"); + pwd=".."; + if (n <= 0 || n >= siz) { + n = 0; + if (inHome) pwd="~"; + else pwd="/"; + } + else n = siz - n; + for (esc.rain(" "+pwd); n < siz; n++) { + esc.rain(" "+parts[n]); + } +} + +void checkBash() { + str env; + if (!strEnv(env, "SHELL")) { + exit(1); + } + int l = env.length(); + if (l < 4 || env.substr(l - 4, 4) != "bash") { + exit(1); + } } int main(int argc,char** argv) { + checkBash(); + escape PS1; for (int i=1;i<argc;i++) { str arg = argv[i];@@ -109,11 +138,10 @@
str user=" "; const char* ipcol = getenv("IPCOLOR"); if (ipcol == NULL || !(std::string(ipcol)=="none"||std::string(ipcol)=="NONE")) { - IP ip; - int ok = ip.get(); user = envorcmd("USER", "whoami"); user = " " + user + " "; - if (ok) PS1.output+=ip.toColor()+" "; + IP ip; + if (ip.get()) PS1.output+=ip.toColor()+" "; }@@ -121,17 +149,7 @@ PS1.add("\\${?}", "202");
PS1.rain(user); PS1.rain(std::to_string(lineno)+" "); PS1.rain(emote()); - str pwd = getpwd(); - if (pwd.back()=='/')pwd.pop_back(); - std::vector<str> parts = split(pwd, '/'); - str base=""; - parts[0] = "/"+parts[0]; - for (int i = 0; parts.size()!=0 && i<2; i++) { - base = " " + parts.back() + base; - parts.pop_back(); - } - if (base.length()==0) base = "/"; - PS1.rain(base); + getpwd(PS1); PS1.rain(" $ "); PS1.set();