Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions Commands/AboutCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using NShell.Shell;
using NShell.Shell.Commands;
using Spectre.Console;

namespace NShell.Commands;

public class AboutCommand : ICustomCommand, IMetadataCommand
{
public string Name => "about";
public string Description => "Display information about NShell.";

public void Execute(ShellContext context, string[] args)
{
AnsiConsole.Clear();

var panel = new Panel(new Markup(
$"[bold cyan]NShell[/] - A Custom C# Interactive Shell\n\n" +
$"[grey]Version:[/] [yellow]{Program.VERSION}[/]\n" +
$"[grey]GitHub:[/] [blue]{Program.GITHUB}[/]\n\n" +
$"[grey]Runtime:[/] [green].NET {Environment.Version}[/]\n" +
$"[grey]Platform:[/] [green]{Environment.OSVersion}[/]\n\n" +
$"[dim]Type [yellow]help[/] to see available commands.[/]"
))
{
Header = new PanelHeader("[bold green] About NShell [/]"),
Border = BoxBorder.Rounded
};

AnsiConsole.Write(panel);
Console.WriteLine();
}
}
70 changes: 70 additions & 0 deletions Commands/AliasCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using NShell.Shell;
using NShell.Shell.Commands;
using NShell.Shell.Config;
using Spectre.Console;

namespace NShell.Commands;

public class AliasCommand : ICustomCommand, IMetadataCommand
{
public string Name => "alias";
public string Description => "Create command aliases (e.g., alias ll='ls -la').";

// Static dictionary to store aliases
public static Dictionary<string, string> Aliases { get; } = new Dictionary<string, string>();
private static readonly ConfigManager _configManager = new ConfigManager();

static AliasCommand()
{
// Load saved aliases on first use
var savedAliases = _configManager.LoadAliases();
foreach (var alias in savedAliases)
{
Aliases[alias.Key] = alias.Value;
}
}

public void Execute(ShellContext context, string[] args)
{
if (args.Length == 0)
{
// List all aliases
if (Aliases.Count == 0)
{
AnsiConsole.MarkupLine("[[[yellow]*[/]]] - No aliases defined.");
return;
}

AnsiConsole.MarkupLine("[bold cyan]Current Aliases:[/]\n");
foreach (var alias in Aliases.OrderBy(a => a.Key))
{
AnsiConsole.MarkupLine($"[yellow]{alias.Key}[/]=[green]'{alias.Value}'[/]");
}
return;
}

// Join all args to handle aliases with spaces
var fullArg = string.Join(' ', args);
var parts = fullArg.Split('=', 2);

if (parts.Length != 2)
{
AnsiConsole.MarkupLine("[[[yellow]*[/]]] - Usage: alias name='command'");
return;
}

string aliasName = parts[0].Trim();
string aliasValue = parts[1].Trim();

// Remove quotes if present
if ((aliasValue.StartsWith("\"") && aliasValue.EndsWith("\"")) ||
(aliasValue.StartsWith("'") && aliasValue.EndsWith("'")))
{
aliasValue = aliasValue.Substring(1, aliasValue.Length - 2);
}

Aliases[aliasName] = aliasValue;
_configManager.SaveAliases(Aliases);
AnsiConsole.MarkupLine($"[[[green]+[/]]] - Alias created: [yellow]{aliasName}[/]=[green]'{aliasValue}'[/]");
}
}
34 changes: 0 additions & 34 deletions Commands/CdCommand.cs

This file was deleted.

16 changes: 16 additions & 0 deletions Commands/ClearCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using NShell.Shell;
using NShell.Shell.Commands;
using Spectre.Console;

namespace NShell.Commands;

public class ClearCommand : ICustomCommand, IMetadataCommand
{
public string Name => "clear";
public string Description => "Clear the terminal screen.";

public void Execute(ShellContext context, string[] args)
{
AnsiConsole.Clear();
}
}
20 changes: 20 additions & 0 deletions Commands/ExitCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using NShell.Shell;
using NShell.Shell.Commands;
using Spectre.Console;

namespace NShell.Commands;

public class ExitCommand : ICustomCommand, IMetadataCommand
{
public string Name => "exit";
public string Description => "Exit the shell.";

public void Execute(ShellContext context, string[] args)
{
// Save history before exiting
Shell.Readline.ReadLine.History.Save();

AnsiConsole.MarkupLine("[bold green]Goodbye![/]");
Environment.Exit(0);
}
}
50 changes: 50 additions & 0 deletions Commands/ExportCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using NShell.Shell;
using NShell.Shell.Commands;
using Spectre.Console;

namespace NShell.Commands;

public class ExportCommand : ICustomCommand, IMetadataCommand
{
public string Name => "export";
public string Description => "Set environment variables (e.g., export VAR=value).";

public void Execute(ShellContext context, string[] args)
{
if (args.Length == 0)
{
// Display all environment variables
var envVars = Environment.GetEnvironmentVariables();
var sortedKeys = envVars.Keys.Cast<string>().OrderBy(k => k);

foreach (var key in sortedKeys)
{
AnsiConsole.MarkupLine($"[cyan]{key}[/]=[yellow]{envVars[key]}[/]");
}
return;
}

foreach (var arg in args)
{
var parts = arg.Split('=', 2);
if (parts.Length != 2)
{
AnsiConsole.MarkupLine($"[[[yellow]*[/]]] - Invalid format: {arg}. Use: export VAR=value");
continue;
}

string varName = parts[0].Trim();
string varValue = parts[1].Trim();

// Remove quotes if present
if ((varValue.StartsWith("\"") && varValue.EndsWith("\"")) ||
(varValue.StartsWith("'") && varValue.EndsWith("'")))
{
varValue = varValue.Substring(1, varValue.Length - 2);
}

Environment.SetEnvironmentVariable(varName, varValue);
AnsiConsole.MarkupLine($"[[[green]+[/]]] - Set [cyan]{varName}[/]=[yellow]{varValue}[/]");
}
}
}
38 changes: 38 additions & 0 deletions Commands/HelpCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using NShell.Shell;
using NShell.Shell.Commands;
using Spectre.Console;

namespace NShell.Commands;

public class HelpCommand : ICustomCommand, IMetadataCommand
{
public string Name => "help";
public string Description => "Display help information about available commands.";

public void Execute(ShellContext context, string[] args)
{
AnsiConsole.MarkupLine("[bold cyan]NShell - Available Commands[/]\n");

var table = new Table();
table.AddColumn("[bold]Command[/]");
table.AddColumn("[bold]Description[/]");

// Add custom commands with descriptions
foreach (var cmd in CommandParser.CustomCommands.Values.OrderBy(c => c.Name))
{
string description = "No description available";
if (cmd is IMetadataCommand metaCmd)
{
description = metaCmd.Description;
}

table.AddRow($"[yellow]{cmd.Name}[/]", description);
}

AnsiConsole.Write(table);

AnsiConsole.MarkupLine($"\n[grey]Total custom commands: {CommandParser.CustomCommands.Count}[/]");
AnsiConsole.MarkupLine($"[grey]Total system commands: {CommandParser.SystemCommands.Count}[/]");
AnsiConsole.MarkupLine("\n[grey]Type a command name to execute it, or use Tab for auto-completion.[/]");
}
}
57 changes: 57 additions & 0 deletions Commands/HistoryCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using NShell.Shell;
using NShell.Shell.Commands;
using NShell.Shell.Readline;
using Spectre.Console;

namespace NShell.Commands;

public class HistoryCommand : ICustomCommand, IMetadataCommand
{
public string Name => "history";
public string Description => "Display command history.";

public void Execute(ShellContext context, string[] args)
{
int displayCount = 20; // Default to last 20 commands
int historyCount = ReadLine.History.Count;

if (args.Length > 0)
{
if (args[0] == "-c" || args[0] == "--clear")
{
// Clear history - not implemented as it would require HistoryManager changes
AnsiConsole.MarkupLine("[[[yellow]*[/]]] - History clearing not yet implemented.");
return;
}
else if (int.TryParse(args[0], out int count))
{
displayCount = count;
}
else
{
AnsiConsole.MarkupLine("[[[yellow]*[/]]] - Usage: history [number] or history -c");
return;
}
}

// Display the last N commands
int startIndex = Math.Max(0, historyCount - displayCount);

if (historyCount == 0)
{
AnsiConsole.MarkupLine("[[[yellow]*[/]]] - No commands in history.");
return;
}

AnsiConsole.MarkupLine($"[bold cyan]Command History (last {Math.Min(displayCount, historyCount)} commands):[/]\n");

for (int i = startIndex; i < historyCount; i++)
{
var command = ReadLine.History.GetAt(i);
if (command != null)
{
AnsiConsole.MarkupLine($" [grey]{i + 1,4}[/] {command}");
}
}
}
}
42 changes: 42 additions & 0 deletions Commands/PrintEnvCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using NShell.Shell;
using NShell.Shell.Commands;
using Spectre.Console;

namespace NShell.Commands;

public class PrintEnvCommand : ICustomCommand, IMetadataCommand
{
public string Name => "printenv";
public string Description => "Print environment variables.";

public void Execute(ShellContext context, string[] args)
{
if (args.Length == 0)
{
// Display all environment variables
var envVars = Environment.GetEnvironmentVariables();
var sortedKeys = envVars.Keys.Cast<string>().OrderBy(k => k);

foreach (var key in sortedKeys)
{
AnsiConsole.MarkupLine($"[cyan]{key}[/]=[yellow]{envVars[key]}[/]");
}
}
else
{
// Display specific environment variables
foreach (var varName in args)
{
var value = Environment.GetEnvironmentVariable(varName);
if (value != null)
{
AnsiConsole.MarkupLine($"[cyan]{varName}[/]=[yellow]{value}[/]");
}
else
{
AnsiConsole.MarkupLine($"[[[yellow]*[/]]] - Variable [cyan]{varName}[/] is not set.");
}
}
}
}
}
Loading
Loading