Pārlūkot izejas kodu

Userland: Add copy and paste commands

You can now copy into the system clipboard like this:
  $ copy hello friends
or like this:
  $ copy < ReadMe.md
or like this:
  $ copy --type png < /res/wallpapers/sunset-retro.png

And paste just with
  $ paste
or to view the copied type:
  $ paste --print-type
Sergey Bugaev 5 gadi atpakaļ
vecāks
revīzija
72acccb051
2 mainītis faili ar 172 papildinājumiem un 0 dzēšanām
  1. 93 0
      Userland/copy.cpp
  2. 79 0
      Userland/paste.cpp

+ 93 - 0
Userland/copy.cpp

@@ -0,0 +1,93 @@
+#include <AK/ByteBuffer.h>
+#include <AK/String.h>
+#include <AK/StringBuilder.h>
+#include <LibCore/CFile.h>
+#include <LibGUI/GClipboard.h>
+#include <LibGUI/GEventLoop.h>
+#include <getopt.h>
+
+struct Options {
+    String data;
+    String type { "text" };
+};
+
+void print_usage(FILE* stream, const char* argv0)
+{
+    fprintf(
+        stream,
+        "Usage:\n"
+        "\t%s [--type type] text\n"
+        "\t%s [--type type] < file\n"
+        "\n"
+        "\t-t type, --type type\tPick a type.\n"
+        "\t-h, --help\t\tPrint this help message.\n",
+        argv0,
+        argv0);
+}
+
+Options parse_options(int argc, char* argv[])
+{
+    Options options;
+
+    static struct option long_options[] = {
+        { "type", required_argument, 0, 't' },
+        { "help", no_argument, 0, 'h' },
+        { 0, 0, 0, 0 }
+    };
+    while (true) {
+        int option_index;
+        int c = getopt_long(argc, argv, "t:h", long_options, &option_index);
+        if (c == -1)
+            break;
+        if (c == 0)
+            c = long_options[option_index].val;
+
+        switch (c) {
+        case 't':
+            options.type = optarg;
+            break;
+        case 'h':
+            print_usage(stdout, argv[0]);
+            exit(0);
+        default:
+            print_usage(stderr, argv[0]);
+            exit(1);
+        }
+    }
+
+    if (optind < argc) {
+        // Copy the rest of our command-line args.
+        StringBuilder builder;
+        bool first = true;
+        for (int i = optind; i < argc; i++) {
+            if (!first)
+                builder.append(' ');
+            first = false;
+            builder.append(argv[i]);
+        }
+        options.data = builder.to_string();
+    } else {
+        // Copy our stdin.
+        CFile c_stdin;
+        bool success = c_stdin.open(
+            STDIN_FILENO,
+            CIODevice::OpenMode::ReadOnly,
+            CFile::ShouldCloseFileDescription::No);
+        ASSERT(success);
+        auto buffer = c_stdin.read_all();
+        dbg() << "Read size " << buffer.size();
+        options.data = String((char*)buffer.data(), buffer.size());
+    }
+
+    return options;
+}
+
+int main(int argc, char* argv[])
+{
+    Options options = parse_options(argc, argv);
+
+    new GEventLoop;
+
+    GClipboard& clipboard = GClipboard::the();
+    clipboard.set_data(options.data, options.type);
+}

+ 79 - 0
Userland/paste.cpp

@@ -0,0 +1,79 @@
+#include <AK/String.h>
+#include <LibGUI/GClipboard.h>
+#include <LibGUI/GEventLoop.h>
+#include <getopt.h>
+
+struct Options {
+    bool print_type { false };
+    bool no_newline { false };
+};
+
+void print_usage(FILE* stream, const char* argv0)
+{
+    fprintf(
+        stream,
+        "Usage:\n"
+        "\t%s [--print-type] [--no-newline]\n"
+        "\n"
+        "\t--print-type\t\tDisplay the copied type.\n"
+        "\t-n, --no-newline\tDo not append a newline.\n"
+        "\t-h, --help\t\tPrint this help message.\n",
+        argv0);
+}
+
+Options parse_options(int argc, char* argv[])
+{
+    Options options;
+
+    static struct option long_options[] = {
+        { "print-type", no_argument, 0, 'p' },
+        { "no-newline", no_argument, 0, 'n' },
+        { "help", no_argument, 0, 'h' },
+        { 0, 0, 0, 0 }
+    };
+    while (true) {
+        int option_index;
+        int c = getopt_long(argc, argv, "hn", long_options, &option_index);
+        if (c == -1)
+            break;
+        if (c == 0)
+            c = long_options[option_index].val;
+
+        switch (c) {
+        case 'p':
+            options.print_type = true;
+            break;
+        case 'n':
+            options.no_newline = true;
+            break;
+        case 'h':
+            print_usage(stdout, argv[0]);
+            exit(0);
+        default:
+            print_usage(stderr, argv[0]);
+            exit(1);
+        }
+    }
+
+    return options;
+}
+
+int main(int argc, char* argv[])
+{
+    Options options = parse_options(argc, argv);
+
+    new GEventLoop;
+
+    GClipboard& clipboard = GClipboard::the();
+    auto data_and_type = clipboard.data_and_type();
+
+    if (!options.print_type) {
+        printf("%s", data_and_type.data.characters());
+        // Append a newline to text contents, but
+        // only if we're not asked not to do this.
+        if (data_and_type.type == "text" && !options.no_newline)
+            putchar('\n');
+    } else {
+        printf("%s\n", data_and_type.type.characters());
+    }
+}