Skip to content

Commit a0953e8

Browse files
author
Thidas Senavirathna
committed
[FEATURE] Command Aliases & Custom Commands #62
1 parent d4b7d20 commit a0953e8

File tree

4 files changed

+193
-19
lines changed

4 files changed

+193
-19
lines changed

src/main/java/com/mycmd/App.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ public static void main(String[] args) {
2424
String input = sc.nextLine().trim();
2525
if (input.isEmpty()) continue;
2626

27+
// Resolve aliases before processing
28+
input = resolveAliases(input, context);
29+
2730
String[] parts = input.split("\\s+");
2831
String cmd = parts[0].toLowerCase();
2932
String[] cmdArgs = Arrays.copyOfRange(parts, 1, parts.length);
@@ -55,6 +58,21 @@ public static void main(String[] args) {
5558
}
5659
}
5760

61+
private static String resolveAliases(String input, ShellContext context) {
62+
String[] parts = input.split("\\s+", 2);
63+
String cmd = parts[0];
64+
String rest = parts.length > 1 ? parts[1] : "";
65+
66+
// Check if the command is an alias
67+
if (context.hasAlias(cmd)) {
68+
String aliasCommand = context.getAlias(cmd);
69+
// Replace the alias with its command, preserving arguments
70+
return rest.isEmpty() ? aliasCommand : aliasCommand + " " + rest;
71+
}
72+
73+
return input;
74+
}
75+
5876
private static void registerCommands(Map<String, Command> commands) {
5977
commands.put("dir", new DirCommand());
6078
commands.put("cd", new CdCommand());
@@ -81,5 +99,7 @@ private static void registerCommands(Map<String, Command> commands) {
8199
commands.put("pwd", new PwdCommand());
82100
commands.put("uptime", new UptimeCommand());
83101
commands.put("clearhistory", new ClearHistoryCommand());
102+
commands.put("alias", new AliasCommand());
103+
commands.put("unalias", new UnaliasCommand());
84104
}
85105
}

src/main/java/com/mycmd/ShellContext.java

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
package com.mycmd;
22

3-
import java.io.File;
4-
import java.util.ArrayList;
5-
import java.util.List;
3+
import java.io.*;
4+
import java.util.*;
65

76
public class ShellContext {
87
private File currentDir;
9-
private List<String> commandHistory;
10-
private final long startTime;
11-
private static final int MAX_HISTORY = 10;
8+
private List<String> history;
9+
private Map<String, String> aliases;
10+
private static final String ALIAS_FILE = ".mycmd_aliases";
11+
private static final int MAX_HISTORY = 100;
1212

1313
public ShellContext() {
1414
this.currentDir = new File(System.getProperty("user.dir"));
15-
this.commandHistory = new ArrayList<>();
16-
this.startTime = System.currentTimeMillis();
15+
this.history = new ArrayList<>();
16+
this.aliases = new HashMap<>();
17+
loadAliases();
1718
}
1819

1920
public File getCurrentDir() {
@@ -24,25 +25,80 @@ public void setCurrentDir(File dir) {
2425
this.currentDir = dir;
2526
}
2627

27-
public long getStartTime() {
28-
return startTime;
28+
public void addToHistory(String command) {
29+
history.add(command);
30+
if (history.size() > MAX_HISTORY) {
31+
history.remove(0);
32+
}
2933
}
3034

31-
public List<String> getCommandHistory() {
32-
return commandHistory;
35+
public List<String> getHistory() {
36+
return new ArrayList<>(history);
3337
}
3438

35-
public void addToHistory(String command) {
36-
if (command != null && !command.trim().isEmpty()) {
37-
commandHistory.add(command.trim());
38-
if (commandHistory.size() > MAX_HISTORY) {
39-
commandHistory.remove(0);
39+
public void clearHistory() {
40+
history.clear();
41+
}
42+
43+
// Alias management methods
44+
public void addAlias(String name, String command) {
45+
aliases.put(name, command);
46+
saveAliases();
47+
}
48+
49+
public void removeAlias(String name) {
50+
aliases.remove(name);
51+
saveAliases();
52+
}
53+
54+
public String getAlias(String name) {
55+
return aliases.get(name);
56+
}
57+
58+
public Map<String, String> getAliases() {
59+
return new HashMap<>(aliases);
60+
}
61+
62+
public boolean hasAlias(String name) {
63+
return aliases.containsKey(name);
64+
}
65+
66+
private void loadAliases() {
67+
File aliasFile = new File(System.getProperty("user.home"), ALIAS_FILE);
68+
if (!aliasFile.exists()) {
69+
return;
70+
}
71+
72+
try (BufferedReader reader = new BufferedReader(new FileReader(aliasFile))) {
73+
String line;
74+
while ((line = reader.readLine()) != null) {
75+
line = line.trim();
76+
if (line.isEmpty() || line.startsWith("#")) {
77+
continue;
78+
}
79+
String[] parts = line.split("=", 2);
80+
if (parts.length == 2) {
81+
String name = parts[0].trim();
82+
String command = parts[1].trim();
83+
aliases.put(name, command);
84+
}
4085
}
86+
} catch (IOException e) {
87+
System.err.println("Warning: Could not load aliases: " + e.getMessage());
4188
}
4289
}
4390

44-
public void clearHistory() {
45-
commandHistory.clear();
91+
private void saveAliases() {
92+
File aliasFile = new File(System.getProperty("user.home"), ALIAS_FILE);
93+
try (BufferedWriter writer = new BufferedWriter(new FileWriter(aliasFile))) {
94+
writer.write("# MyCMD Aliases Configuration\n");
95+
writer.write("# Format: aliasName=command\n\n");
96+
for (Map.Entry<String, String> entry : aliases.entrySet()) {
97+
writer.write(entry.getKey() + "=" + entry.getValue() + "\n");
98+
}
99+
} catch (IOException e) {
100+
System.err.println("Warning: Could not save aliases: " + e.getMessage());
101+
}
46102
}
47103

48104
/**
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.mycmd.commands;
2+
3+
import com.mycmd.ShellContext;
4+
import java.util.Map;
5+
6+
public class AliasCommand implements Command {
7+
@Override
8+
public void execute(String[] args, ShellContext context) {
9+
if (args.length == 0) {
10+
// List all aliases
11+
Map<String, String> aliases = context.getAliases();
12+
if (aliases.isEmpty()) {
13+
System.out.println("No aliases defined.");
14+
} else {
15+
System.out.println("Current aliases:");
16+
for (Map.Entry<String, String> entry : aliases.entrySet()) {
17+
System.out.println(" " + entry.getKey() + "=\"" + entry.getValue() + "\"");
18+
}
19+
}
20+
} else {
21+
// Create alias: alias name="command" or alias name=command
22+
String input = String.join(" ", args);
23+
24+
if (!input.contains("=")) {
25+
System.out.println("Usage: alias name=\"command\"");
26+
System.out.println("Example: alias ll=\"dir /w\"");
27+
return;
28+
}
29+
30+
String[] parts = input.split("=", 2);
31+
String name = parts[0].trim();
32+
String command = parts[1].trim();
33+
34+
// Remove quotes if present
35+
if (command.startsWith("\"") && command.endsWith("\"")) {
36+
command = command.substring(1, command.length() - 1);
37+
}
38+
39+
// Validate alias name
40+
if (name.isEmpty() || name.contains(" ")) {
41+
System.out.println("Error: Alias name cannot be empty or contain spaces.");
42+
return;
43+
}
44+
45+
if (command.isEmpty()) {
46+
System.out.println("Error: Alias command cannot be empty.");
47+
return;
48+
}
49+
50+
// Check for circular reference
51+
if (command.split("\\s+")[0].equalsIgnoreCase(name)) {
52+
System.out.println("Error: Cannot create circular alias reference.");
53+
return;
54+
}
55+
56+
context.addAlias(name, command);
57+
System.out.println("Alias created: " + name + "=\"" + command + "\"");
58+
}
59+
}
60+
61+
@Override
62+
public String getHelp() {
63+
return "alias [name=\"command\"] - Create or list command aliases\n" +
64+
" alias - List all aliases\n" +
65+
" alias name=\"command\" - Create new alias\n" +
66+
" Example: alias ll=\"dir /w\"";
67+
}
68+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.mycmd.commands;
2+
3+
import com.mycmd.ShellContext;
4+
5+
public class UnaliasCommand implements Command {
6+
@Override
7+
public void execute(String[] args, ShellContext context) {
8+
if (args.length == 0) {
9+
System.out.println("Usage: unalias <name>");
10+
System.out.println("Example: unalias ll");
11+
return;
12+
}
13+
14+
String aliasName = args[0].trim();
15+
16+
if (!context.hasAlias(aliasName)) {
17+
System.out.println("Error: Alias '" + aliasName + "' not found.");
18+
return;
19+
}
20+
21+
context.removeAlias(aliasName);
22+
System.out.println("Alias removed: " + aliasName);
23+
}
24+
25+
@Override
26+
public String getHelp() {
27+
return "unalias <name> - Remove a command alias\n" +
28+
" Example: unalias ll";
29+
}
30+
}

0 commit comments

Comments
 (0)