aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lua_api.c44
-rw-r--r--src/lush.c48
2 files changed, 67 insertions, 25 deletions
diff --git a/src/lua_api.c b/src/lua_api.c
index 4b5de86..7bac763 100644
--- a/src/lua_api.c
+++ b/src/lua_api.c
@@ -20,9 +20,11 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
+#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
// global for checking if debug_mode is toggled
@@ -110,6 +112,48 @@ static int l_debug(lua_State *L) {
return 0;
}
+static int l_cd(lua_State *L) {
+ bool rc;
+ uid_t uid = getuid();
+ struct passwd *pw = getpwuid(uid);
+ if (!pw) {
+ perror("retrieve home dir");
+ rc = false;
+ lua_pushboolean(L, rc);
+ return 1;
+ }
+
+ const char *newdir = luaL_checkstring(L, 1);
+ if (newdir == NULL) {
+ if (chdir(pw->pw_dir) != 0) {
+ perror("lush: cd");
+ }
+ } else {
+ char path[PATH_MAX];
+ char extended_path[PATH_MAX];
+ char *tilda = strchr(newdir, '~');
+ if (tilda) {
+ strcpy(path, pw->pw_dir);
+ strcat(path, tilda + 1);
+ } else {
+ strcpy(path, newdir);
+ }
+ char *exp_path = realpath(path, extended_path);
+ if (!exp_path) {
+ perror("realpath");
+ rc = false;
+ lua_pushboolean(L, rc);
+ return 1;
+ }
+ if (chdir(exp_path) != 0) {
+ perror("lush: cd");
+ }
+ }
+ rc = true;
+ lua_pushboolean(L, rc);
+ return 1;
+}
+
// -- register Lua functions --
void lua_register_api(lua_State *L) {
diff --git a/src/lush.c b/src/lush.c
index f35a849..facdff2 100644
--- a/src/lush.c
+++ b/src/lush.c
@@ -147,30 +147,6 @@ static void reset_terminal_mode(struct termios *orig_termios) {
tcsetattr(STDIN_FILENO, TCSANOW, orig_termios);
}
-static void print_prompt() {
- char *username = getenv("USER");
- char device_name[256];
- gethostname(device_name, sizeof(device_name));
- char *cwd = getcwd(NULL, 0);
-
- // Replace /home/<user> with ~
- char *home_prefix = "/home/";
- size_t home_len = strlen(home_prefix) + strlen(username);
- char *prompt_cwd;
- if (strncmp(cwd, home_prefix, strlen(home_prefix)) == 0 &&
- strncmp(cwd + strlen(home_prefix), username, strlen(username)) == 0) {
- prompt_cwd = malloc(strlen(cwd) - home_len +
- 2); // 1 for ~ and 1 for null terminator
- snprintf(prompt_cwd, strlen(cwd) - home_len + 2, "~%s", cwd + home_len);
- } else {
- prompt_cwd = strdup(cwd);
- }
-
- // Print the prompt
- printf("[%s@%s:%s] ", username, device_name, prompt_cwd);
- free(cwd);
-}
-
int get_terminal_width() {
struct winsize w;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == -1) {
@@ -518,7 +494,28 @@ int main() {
int status = 0;
while (true) {
// Prompt
- print_prompt();
+ char *username = getenv("USER");
+ char device_name[256];
+ gethostname(device_name, sizeof(device_name));
+ char *cwd = getcwd(NULL, 0);
+
+ // Replace /home/<user> with ~
+ char *home_prefix = "/home/";
+ size_t home_len = strlen(home_prefix) + strlen(username);
+ char *prompt_cwd;
+ if (strncmp(cwd, home_prefix, strlen(home_prefix)) == 0 &&
+ strncmp(cwd + strlen(home_prefix), username, strlen(username)) ==
+ 0) {
+ prompt_cwd = malloc(strlen(cwd) - home_len +
+ 2); // 1 for ~ and 1 for null terminator
+ snprintf(prompt_cwd, strlen(cwd) - home_len + 2, "~%s",
+ cwd + home_len);
+ } else {
+ prompt_cwd = strdup(cwd);
+ }
+
+ // Print the prompt
+ printf("[%s@%s:%s] ", username, device_name, prompt_cwd);
char *line = lush_read_line();
printf("\n");
if (line == NULL || strlen(line) == 0) {
@@ -536,6 +533,7 @@ int main() {
for (int i = 0; args[i]; i++) {
free(args[i]);
}
+ free(cwd);
free(args);
free(commands);
free(line);