-
Notifications
You must be signed in to change notification settings - Fork 0
/
promptus.c
162 lines (140 loc) · 3.23 KB
/
promptus.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <limits.h>
#include <stdbool.h>
enum COLOR_CODES {
COLOR_PWD,
COLOR_PROMPT,
COLOR_PROMPT_ERR,
COLOR_PROMPT_BG,
COLOR_PREFIX,
COLOR_RESET,
};
#include "config.h"
// BACKGROUND_CODE is the exit status of a program that's
// been backgrounded. If you're unsure, try running something
// like vim, doing control-z, and then 'echo $?'.
#ifndef BACKGROUND_CODE
# ifdef __APPLE__ // macOS
# define BACKGROUND_CODE 146
# else // Linux, presumably
# define BACKGROUND_CODE 148
# endif
#endif
static bool samefile(const char* path1, const char* path2) {
struct stat stat1, stat2;
if (path1 != NULL && path2 != NULL
&& stat(path1, &stat1) == 0
&& stat(path2, &stat2) == 0
&& stat1.st_dev == stat2.st_dev
&& stat1.st_ino == stat2.st_ino) {
return true;
} else {
return false;
}
}
static void getrealcwd(char* buf, size_t size) {
char* pwd;
pwd = getenv("PWD");
if (samefile(".", pwd)) {
strncpy(buf, pwd, size);
} else {
(void)getcwd(buf, size);
}
}
static char* basename(const char* path) {
char* r = strrchr(path, '/');
if (r && r != path) {
r++;
}
return r;
}
int main(int argc, char** argv) {
// get the shell so we know which escapes to use
const char* lescape = "";
const char* rescape = "";
const char* prefix = "";
const char* shell = getenv("SHELL");
if (shell) {
const char* bshell = basename(shell);
if (0 == strcmp(bshell, "zsh")) {
lescape = "%{";
rescape = "%}";
} else if (0 == strcmp(bshell, "bash")) {
lescape = "\\[";
rescape = "\\]";
}
}
#if PROMPT_STATUS
int laststatus = 0;
if (argc > 1) {
laststatus = atoi(argv[1]);
}
#endif // PROMPT_STATUS
#if ENABLE_PY_VENV
prefix = getenv("VIRTUAL_ENV_PROMPT");
if (!prefix) {
prefix = "";
}
#endif // ENABLE_PY_VENV
printf("%s%s%s%s",
lescape,
colors[COLOR_PREFIX],
rescape,
prefix);
#if SHOW_PWD
char pwd[PATH_MAX] = {0};
getrealcwd(pwd, PATH_MAX-1);
char* _pwd = pwd;
# if PWD_BASENAME
_pwd = basename(pwd);
# endif // PWD_BASENAME
# if PWD_ABBREV_HOME
const char* home = getenv("HOME");
if (home) {
if (samefile(pwd, home)) {
_pwd = "~";
}
# if !PWD_BASENAME
// replace instance of $HOME with ~ if applicable
if (!strncmp(_pwd, home, strlen(home))) {
_pwd += strlen(home) - 1;
*_pwd = '~';
}
# endif // not PWD_BASENAME
}
# endif // PWD_ABBREV_HOME
printf("%s%s%s%s%s%s%s ",
lescape,
colors[COLOR_PWD],
rescape,
_pwd,
lescape,
colors[COLOR_RESET],
rescape);
#endif // SHOW_PWD
// prompt color
const char* pcolor = colors[COLOR_PROMPT];
#if PROMPT_STATUS
if (laststatus == 0 || laststatus == 130) {
pcolor = colors[COLOR_PROMPT];
} else if (laststatus == BACKGROUND_CODE) {
pcolor = colors[COLOR_PROMPT_BG];
} else {
pcolor = colors[COLOR_PROMPT_ERR];
}
#endif // PROMPT_STATUS
printf("%s%s%s%s%s%s%s ",
lescape,
pcolor,
rescape,
prompt,
lescape,
colors[COLOR_RESET],
rescape);
return 0;
}