1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 01:07:36 +00:00

Shell: Add support for 'immediate' expressions as variable substitutions

This commit adds a few basic variable substitution operations:
- length
    Find the length of a string or a list
- length_across
    Find the lengths of things inside a list
- remove_{suffix,prefix}
    Remove a suffix or a prefix from all the passed values
- regex_replace
    Replace all matches of a given regex with a given template
- split
    Split the given string with the given delimiter (or to its
    code points if the delimiter is empty)
- concat_lists
    concatenates any given lists into one

Closes #4316 (the ancient version of this same feature)
This commit is contained in:
AnotherTest 2021-03-05 16:33:23 +03:30 committed by Andreas Kling
parent a303b69caa
commit a45b2ea6fb
16 changed files with 911 additions and 37 deletions

View file

@ -73,6 +73,11 @@ struct Position {
bool contains(size_t offset) const { return start_offset <= offset && offset <= end_offset; }
};
struct NameWithPosition {
String name;
Position position;
};
struct FdRedirection;
struct Rewiring : public RefCounted<Rewiring> {
int old_fd { -1 };
@ -330,6 +335,7 @@ public:
virtual ~StringValue();
virtual bool is_string() const override { return m_split.is_null(); }
virtual bool is_list() const override { return !m_split.is_null(); }
NonnullRefPtr<Value> resolve_without_cast(RefPtr<Shell>) override;
StringValue(String string, String split_by = {}, bool keep_empty = false)
: m_string(move(string))
, m_split(move(split_by))
@ -472,6 +478,7 @@ public:
Glob,
HistoryEvent,
IfCond,
ImmediateExpression,
Join,
Juxtaposition,
ListConcatenate,
@ -488,6 +495,7 @@ public:
StringPartCompose,
Subshell,
SyntaxError,
SyntheticValue,
Tilde,
VariableDeclarations,
WriteAppendRedirection,
@ -813,10 +821,6 @@ private:
class FunctionDeclaration final : public Node {
public:
struct NameWithPosition {
String name;
Position position;
};
FunctionDeclaration(Position, NameWithPosition name, Vector<NameWithPosition> argument_names, RefPtr<AST::Node> body);
virtual ~FunctionDeclaration();
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
@ -994,6 +998,31 @@ private:
Optional<Position> m_else_position;
};
class ImmediateExpression final : public Node {
public:
ImmediateExpression(Position, NameWithPosition function, NonnullRefPtrVector<AST::Node> arguments, Optional<Position> closing_brace_position);
virtual ~ImmediateExpression();
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
const NonnullRefPtrVector<Node>& arguments() const { return m_arguments; }
const auto& function() const { return m_function; }
const String& function_name() const { return m_function.name; }
const Position& function_position() const { return m_function.position; }
bool has_closing_brace() const { return m_closing_brace_position.has_value(); }
private:
NODE(ImmediateExpression);
virtual void dump(int level) const override;
virtual RefPtr<Value> run(RefPtr<Shell>) override;
virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
Vector<Line::CompletionSuggestion> complete_for_editor(Shell&, size_t, const HitTestResult&) override;
virtual HitTestResult hit_test_position(size_t) const override;
NonnullRefPtrVector<AST::Node> m_arguments;
NameWithPosition m_function;
Optional<Position> m_closing_brace_position;
};
class Join final : public Node {
public:
Join(Position, NonnullRefPtr<Node>, NonnullRefPtr<Node>);
@ -1301,6 +1330,23 @@ private:
bool m_is_continuable { false };
};
class SyntheticNode final : public Node {
public:
SyntheticNode(Position, NonnullRefPtr<Value>);
virtual ~SyntheticNode() = default;
virtual void visit(NodeVisitor& visitor) override { visitor.visit(this); }
const Value& value() const { return m_value; }
private:
NODE(SyntheticValue);
virtual void dump(int level) const override;
virtual RefPtr<Value> run(RefPtr<Shell>) override;
virtual void highlight_in_editor(Line::Editor&, Shell&, HighlightMetadata = {}) override;
NonnullRefPtr<Value> m_value;
};
class Tilde final : public Node {
public:
Tilde(Position, String);