Compare commits
No commits in common. "6a5e11bf1887355910333045f195559d463b64bd" and "db53ee6c3bdd8d14c196f06b6377f2418779f82d" have entirely different histories.
6a5e11bf18
...
db53ee6c3b
47
.gitignore
vendored
47
.gitignore
vendored
@ -1,23 +1,38 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/d,macos,linux,windows
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=d,macos,linux,windows
|
||||||
|
|
||||||
|
### D ###
|
||||||
|
# Compiled Object files
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
|
||||||
|
# DUB
|
||||||
.dub
|
.dub
|
||||||
docs.json
|
docs.json
|
||||||
__dummy.html
|
__dummy.html
|
||||||
docs/
|
docs/
|
||||||
/prim
|
|
||||||
prim.so
|
|
||||||
prim.dylib
|
|
||||||
prim.dll
|
|
||||||
prim.a
|
|
||||||
prim.lib
|
|
||||||
prim-test-*
|
|
||||||
*.exe
|
|
||||||
*.pdb
|
|
||||||
*.o
|
|
||||||
*.obj
|
|
||||||
*.lst
|
|
||||||
dub.selections.json
|
|
||||||
|
|
||||||
# Created by https://www.toptal.com/developers/gitignore/api/macos,windows,linux
|
# Code coverage
|
||||||
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,linux
|
*.lst
|
||||||
|
|
||||||
|
### D Patch ###
|
||||||
|
# Test Executables
|
||||||
|
*-test-*
|
||||||
|
|
||||||
|
# Comment to allow dub lock file to be version controlled as well
|
||||||
|
dub.selections.json
|
||||||
|
|
||||||
### Linux ###
|
### Linux ###
|
||||||
*~
|
*~
|
||||||
@ -92,5 +107,5 @@ $RECYCLE.BIN/
|
|||||||
# Windows shortcuts
|
# Windows shortcuts
|
||||||
*.lnk
|
*.lnk
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,linux
|
# End of https://www.toptal.com/developers/gitignore/api/d,macos,linux,windows
|
||||||
|
|
||||||
|
2
dub.json
2
dub.json
@ -3,8 +3,6 @@
|
|||||||
"zerocool"
|
"zerocool"
|
||||||
],
|
],
|
||||||
"copyright": "Copyright © 2023, zerocool",
|
"copyright": "Copyright © 2023, zerocool",
|
||||||
"dependencies": {
|
|
||||||
},
|
|
||||||
"description": "A minimal D application.",
|
"description": "A minimal D application.",
|
||||||
"license": "proprietary",
|
"license": "proprietary",
|
||||||
"name": "prim"
|
"name": "prim"
|
||||||
|
16
hook.zsh
16
hook.zsh
@ -1,9 +1,13 @@
|
|||||||
prompt_precmd() {
|
|
||||||
export PS1=$'`prim --ps1 --col "$COLUMNS" --row "$LINES" --status "$?" --pchar "*"`'
|
|
||||||
export RPS1=$'`prim --rps1 --col "$COLUMNS" --row "$LINES" --status "$?"`'
|
|
||||||
}
|
|
||||||
|
|
||||||
autoload -Uz add-zsh-hook
|
|
||||||
setopt promptsubst
|
setopt promptsubst
|
||||||
|
|
||||||
|
prompt_precmd() {
|
||||||
|
export PS1=`prim --ps1 --col $COLUMNS --row $LINES --status $?`
|
||||||
|
export RPS1=`prim --rps1 --col $COLUMNS --row $LINES --status $?`
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_preexec() {
|
||||||
|
print -P `prim --preexec --col $COLUMNS --row $LINES --status $?`
|
||||||
|
}
|
||||||
|
|
||||||
add-zsh-hook precmd prompt_precmd
|
add-zsh-hook precmd prompt_precmd
|
||||||
|
add-zsh-hook preexec prompt_preexec
|
||||||
|
48
source/app.d
48
source/app.d
@ -14,48 +14,34 @@ Opts defaultOpts() {
|
|||||||
Opts opts;
|
Opts opts;
|
||||||
|
|
||||||
opts.pathlen = 3;
|
opts.pathlen = 3;
|
||||||
opts.pchar = "*";
|
|
||||||
|
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printHelp(GetoptResult args) {
|
|
||||||
defaultGetoptPrinter("prim prompt:\n", args.options);
|
|
||||||
writeln("\nEnvironment:\n",
|
|
||||||
"\tNO_COLOR\tsee https://no-color.org");
|
|
||||||
}
|
|
||||||
|
|
||||||
void main(string[] argv) {
|
void main(string[] argv) {
|
||||||
Opts opts = defaultOpts();
|
Opts opts = defaultOpts();
|
||||||
|
|
||||||
try {
|
GetoptResult args = getopt(
|
||||||
|
argv,
|
||||||
|
std.getopt.config.bundling,
|
||||||
|
"ps1|p", "print PS1", &opts.ps1,
|
||||||
|
"rps1|r", "print RPS1", &opts.rps1,
|
||||||
|
"preexec|x", "print preexec", &opts.preexec,
|
||||||
|
|
||||||
GetoptResult args = getopt(
|
std.getopt.config.required,
|
||||||
argv,
|
"col", "terminal width", &opts.col,
|
||||||
std.getopt.config.bundling,
|
|
||||||
"ps1|p", "print PS1", &opts.ps1,
|
|
||||||
"rps1|r", "print RPS1", &opts.rps1,
|
|
||||||
"preexec|x", "print preexec", &opts.preexec,
|
|
||||||
|
|
||||||
std.getopt.config.required,
|
std.getopt.config.required,
|
||||||
"col", "terminal width", &opts.col,
|
"row", "terminal height", &opts.row,
|
||||||
|
|
||||||
std.getopt.config.required,
|
std.getopt.config.required,
|
||||||
"row", "terminal height", &opts.row,
|
"status", "previous command exit code", &opts.status,
|
||||||
|
|
||||||
std.getopt.config.required,
|
"pathlen", "set length of displayed path", &opts.pathlen,
|
||||||
"status", "previous command exit code", &opts.status,
|
);
|
||||||
|
|
||||||
"pathlen", "set length of displayed path", &opts.pathlen,
|
if (args.helpWanted) {
|
||||||
"pchar", "override default prompt character", &opts.pchar,
|
defaultGetoptPrinter("prim", args.options);
|
||||||
);
|
|
||||||
|
|
||||||
if (args.helpWanted) {
|
|
||||||
printHelp(args);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
writeln(e.msg);
|
|
||||||
writeln("try '--help' for more information");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dorun(opts);
|
dorun(opts);
|
||||||
@ -67,7 +53,7 @@ void dorun(Opts opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opts.preexec) {
|
if (opts.preexec) {
|
||||||
preexec(opts).write();
|
preexec(opts.col).write();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.rps1) {
|
if (opts.rps1) {
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
module comp.git;
|
|
||||||
|
|
||||||
import std.stdio;
|
|
||||||
import std.file : dirEntries, SpanMode;
|
|
||||||
import std.process;
|
|
||||||
import std.string : strip;
|
|
||||||
|
|
||||||
string gitBranch() {
|
|
||||||
auto result = execute(["git", "rev-parse", "--abbrev-ref", "HEAD"]);
|
|
||||||
|
|
||||||
if (result.status != 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return result.output.strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
string gitStatus() {
|
|
||||||
auto result = execute(["git", "status", "--porcelain"]);
|
|
||||||
|
|
||||||
if (result.status != 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (result.output.length >= 1) {
|
|
||||||
return "*";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
@ -4,7 +4,7 @@ string hr(int col) {
|
|||||||
string ps;
|
string ps;
|
||||||
|
|
||||||
foreach (i; 0 .. col) {
|
foreach (i; 0 .. col) {
|
||||||
ps ~= '─';
|
ps ~= '—';
|
||||||
}
|
}
|
||||||
|
|
||||||
return ps;
|
return ps;
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
module comp.path;
|
|
||||||
|
|
||||||
import std.conv;
|
|
||||||
import std.regex;
|
|
||||||
import std.array;
|
|
||||||
|
|
||||||
import std.file : getcwd;
|
|
||||||
import std.path : expandTilde;
|
|
||||||
import std.algorithm : reverse;
|
|
||||||
|
|
||||||
string path(int pathlen) {
|
|
||||||
string ps;
|
|
||||||
|
|
||||||
string home = expandTilde("~");
|
|
||||||
string path = replaceFirst(getcwd(), regex(home), "~");
|
|
||||||
|
|
||||||
string[] splitPath = path.split("/").reverse();
|
|
||||||
|
|
||||||
string[] revSplitPath;
|
|
||||||
for (int i = 0; i < pathlen; i++) {
|
|
||||||
if (i >= splitPath.length)
|
|
||||||
break;
|
|
||||||
|
|
||||||
revSplitPath ~= splitPath[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
splitPath = revSplitPath.reverse();
|
|
||||||
|
|
||||||
ps ~= splitPath.join("/");
|
|
||||||
|
|
||||||
return ps ~ "/";
|
|
||||||
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
module comp.ssh;
|
|
||||||
|
|
||||||
import std.process : environment;
|
|
||||||
import std.socket : Socket;
|
|
||||||
|
|
||||||
string ssh() {
|
|
||||||
string ssh = environment.get("SSH_TTY");
|
|
||||||
string username = environment.get("USER");
|
|
||||||
username = username ? username : "";
|
|
||||||
|
|
||||||
if (!ssh) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto s = new Socket();
|
|
||||||
scope (exit)
|
|
||||||
s.close();
|
|
||||||
|
|
||||||
string hostname = s.hostName;
|
|
||||||
|
|
||||||
return username ~ "@" ~ hostname;
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ struct Opts {
|
|||||||
bool preexec;
|
bool preexec;
|
||||||
|
|
||||||
int pathlen;
|
int pathlen;
|
||||||
string pchar;
|
|
||||||
|
|
||||||
int col;
|
int col;
|
||||||
int row;
|
int row;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
module prompt.preexec;
|
module prompt.preexec;
|
||||||
|
|
||||||
import prim.opt;
|
|
||||||
import comp.hr;
|
import comp.hr;
|
||||||
|
|
||||||
import style;
|
import style;
|
||||||
import style.color;
|
import style.color;
|
||||||
|
|
||||||
string preexec(Opts opt) {
|
string preexec(int col) {
|
||||||
return "";
|
return hr(col).set(Color.black);
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,7 @@ module prompt.ps1;
|
|||||||
import std.conv;
|
import std.conv;
|
||||||
|
|
||||||
import prim.opt;
|
import prim.opt;
|
||||||
|
|
||||||
import comp.hr;
|
import comp.hr;
|
||||||
import comp.path;
|
|
||||||
import comp.ssh;
|
|
||||||
|
|
||||||
import style;
|
import style;
|
||||||
import style.color;
|
import style.color;
|
||||||
@ -15,14 +12,14 @@ import style.font;
|
|||||||
string ps1(Opts opt) {
|
string ps1(Opts opt) {
|
||||||
string ps;
|
string ps;
|
||||||
|
|
||||||
string pathstr = path(opt.pathlen).set(Color.magenta).set(Font.italic).set(Font.bold);
|
// divider
|
||||||
|
ps ~= hr(opt.col).set(Color.black);
|
||||||
|
|
||||||
ps ~= "\n";
|
// previous command status
|
||||||
ps ~= (",-(" ~ pathstr ~ ")".set(Color.black)).set(Color.black);
|
ps ~= ("(" ~ to!string(opt.status) ~ ") ").set(Color.black);
|
||||||
ps ~= " " ~ ssh().set(Color.cyan);
|
|
||||||
ps ~= "\n";
|
// prompt char
|
||||||
|
ps ~= "|> ".set(Font.bold).set(opt.status == 0 ? Color.green : Color.red);
|
||||||
|
|
||||||
ps ~= ("`-(" ~ to!string(opt.status).set(Color.yellow) ~ ") ".set(Color.black)).set(Color.black); // prompt char
|
|
||||||
ps ~= (opt.pchar ~ " ").set(Font.bold).set(opt.status == 0 ? Color.green : Color.red);
|
|
||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
module prompt.rps1;
|
module prompt.rps1;
|
||||||
|
|
||||||
import prim.opt;
|
import std.conv;
|
||||||
|
import std.regex;
|
||||||
|
import std.array;
|
||||||
|
|
||||||
import comp.path;
|
import std.file : getcwd;
|
||||||
import comp.git;
|
import std.path : expandTilde;
|
||||||
|
import std.algorithm : reverse;
|
||||||
|
|
||||||
|
import prim.opt;
|
||||||
|
|
||||||
import style;
|
import style;
|
||||||
import style.color;
|
import style.color;
|
||||||
@ -12,8 +17,22 @@ import style.font;
|
|||||||
string rps1(Opts opt) {
|
string rps1(Opts opt) {
|
||||||
string ps;
|
string ps;
|
||||||
|
|
||||||
ps ~= (gitBranch()).set(Font.bold).set(Color.cyan);
|
string home = expandTilde("~");
|
||||||
ps ~= (gitStatus());
|
string path = replaceFirst(getcwd(), regex(home), "~");
|
||||||
|
|
||||||
return ps;
|
string[] splitPath = path.split("/").reverse();
|
||||||
|
|
||||||
|
string[] revSplitPath;
|
||||||
|
for (int i = 0; i < opt.pathlen; i++) {
|
||||||
|
if (i >= splitPath.length)
|
||||||
|
break;
|
||||||
|
|
||||||
|
revSplitPath ~= splitPath[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
splitPath = revSplitPath.reverse();
|
||||||
|
|
||||||
|
ps ~= splitPath.join("/");
|
||||||
|
|
||||||
|
return ps.set(Font.italic).set(Color.yellow);
|
||||||
}
|
}
|
||||||
|
@ -38,16 +38,3 @@ enum Bg {
|
|||||||
def,
|
def,
|
||||||
reset = 0
|
reset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BrightBg {
|
|
||||||
black = 100,
|
|
||||||
red,
|
|
||||||
green,
|
|
||||||
yellow,
|
|
||||||
blue,
|
|
||||||
magenta,
|
|
||||||
cyan,
|
|
||||||
white,
|
|
||||||
def,
|
|
||||||
reset = 0
|
|
||||||
}
|
|
||||||
|
@ -1,22 +1,9 @@
|
|||||||
module style;
|
module style;
|
||||||
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import core.stdc.stdlib : getenv;
|
|
||||||
|
|
||||||
import style.color;
|
import style.color;
|
||||||
|
|
||||||
string set(string s, int code) {
|
string set(string s, int code) {
|
||||||
if (getenv("NO_COLOR"))
|
return ("%{\x1b[" ~ to!string(code) ~ "m%}") ~ s ~ ("%{\x1b[" ~ to!string((Color.reset + 0)) ~ "m%}");
|
||||||
return s;
|
|
||||||
|
|
||||||
return ("%{\x1b[" ~ to!string(code) ~ "m%}") ~ s ~ (
|
|
||||||
"%{\x1b[" ~ to!string((Color.reset + 0)) ~ "m%}");
|
|
||||||
}
|
|
||||||
|
|
||||||
string set(string s, int code, bool close) {
|
|
||||||
if (getenv("NO_COLOR"))
|
|
||||||
return s;
|
|
||||||
|
|
||||||
return ("%{\x1b[" ~ to!string(code) ~ "m%}") ~ s ~ (close ? (
|
|
||||||
"%{\x1b[" ~ to!string((Color.reset + 0)) ~ "m%}") : "");
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user