mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 16:25:06 +00:00
Shell: Implement a "cd history" (cdh) builtin
`cdh` with no arguments dumps the last 8 cd calls in history, and `cdh [index]` can be used to cd to re-run a specific index from that history. `cdh` itself it a thin wrapper of the `cd` builtin. There's definitely some improvements that can be made for this command, but this seems like a good starting point for getting a feel for it and ideas for changing it in the future. It's not entirely clear whether we should be storing the resolved path - or simply just the last argument passed to cd. For now we just use the last path passed into cd as this seemed like the better option for now. This means: * invalid paths will still be stored in history (potentially useful) * cdh's can be repeated for duplicate directory names * the history looks a little nicer on the eyes It might make sense to use resolved paths. Closes #397
This commit is contained in:
parent
5e817ee678
commit
d0fb816ac3
2 changed files with 41 additions and 0 deletions
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <AK/CircularQueue.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
|
||||||
struct GlobalState {
|
struct GlobalState {
|
||||||
|
@ -43,6 +44,7 @@ struct GlobalState {
|
||||||
bool was_resized { false };
|
bool was_resized { false };
|
||||||
int last_return_code { 0 };
|
int last_return_code { 0 };
|
||||||
Vector<String> directory_stack;
|
Vector<String> directory_stack;
|
||||||
|
CircularQueue<String, 8> cd_history; // FIXME: have a configurable cd history length
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GlobalState g;
|
extern GlobalState g;
|
||||||
|
|
|
@ -191,7 +191,11 @@ static int sh_cd(int argc, const char** argv)
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
new_path = g.home;
|
new_path = g.home;
|
||||||
|
if (g.cd_history.is_empty() || g.cd_history.last() != g.home)
|
||||||
|
g.cd_history.enqueue(g.home);
|
||||||
} else {
|
} else {
|
||||||
|
if (g.cd_history.is_empty() || g.cd_history.last() != argv[1])
|
||||||
|
g.cd_history.enqueue(argv[1]);
|
||||||
if (strcmp(argv[1], "-") == 0) {
|
if (strcmp(argv[1], "-") == 0) {
|
||||||
char* oldpwd = getenv("OLDPWD");
|
char* oldpwd = getenv("OLDPWD");
|
||||||
if (oldpwd == nullptr)
|
if (oldpwd == nullptr)
|
||||||
|
@ -241,6 +245,37 @@ static int sh_cd(int argc, const char** argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sh_cdh(int argc, const char** argv)
|
||||||
|
{
|
||||||
|
if (argc > 2) {
|
||||||
|
fprintf(stderr, "usage: cdh [index]\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
if (g.cd_history.size() == 0) {
|
||||||
|
printf("cdh: no history available\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = g.cd_history.size() - 1; i >= 0; --i)
|
||||||
|
printf("%lu: %s\n", g.cd_history.size() - i, g.cd_history.at(i).characters());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
size_t cd_history_index = String(argv[1]).to_uint(ok);
|
||||||
|
|
||||||
|
if (!ok || cd_history_index < 1 || cd_history_index > g.cd_history.size()) {
|
||||||
|
fprintf(stderr, "usage: cdh [index]\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* path = g.cd_history.at(g.cd_history.size() - cd_history_index).characters();
|
||||||
|
const char* cd_args[] = { "cd", path };
|
||||||
|
return sh_cd(2, cd_args);
|
||||||
|
}
|
||||||
|
|
||||||
static int sh_history(int, const char**)
|
static int sh_history(int, const char**)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < editor.history().size(); ++i) {
|
for (size_t i = 0; i < editor.history().size(); ++i) {
|
||||||
|
@ -489,6 +524,10 @@ static bool handle_builtin(int argc, const char** argv, int& retval)
|
||||||
retval = sh_cd(argc, argv);
|
retval = sh_cd(argc, argv);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(argv[0], "cdh")) {
|
||||||
|
retval = sh_cdh(argc, argv);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (!strcmp(argv[0], "pwd")) {
|
if (!strcmp(argv[0], "pwd")) {
|
||||||
retval = sh_pwd(argc, argv);
|
retval = sh_pwd(argc, argv);
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue