// libvle -- library for building Vim-like applications
// Copyright (C) 2022 xaizek <xaizek@posteo.net>
//
// This file is part of libvle.
//
// libvle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libvle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libvle. If not, see <https://www.gnu.org/licenses/>.
#include "Commands.hpp"
#include <cstring>
#include <deque>
#include <functional>
#include <string>
#include <utility>
#include <vector>
#include "engine/cmds.h"
using namespace vle;
static int completeLine(const char cmd_line[], void *extra_arg);
static int completeArgs(int id, const cmd_info_t *cmd_info, int arg_pos,
void *extra_arg);
static int swapRange(void);
static int resolveMark(char mark);
static char * expandMacros(const char str[], int for_shell, int *usr1,
int *usr2);
static char * expandEnvVars(const char *str);
static void post(int id);
static void selectRange(int id, const cmd_info_t *cmd_info);
static int skipAtBeginning(int id, const char *args);
static int cmdHandler(const cmd_info_t *cmd_info);
Commands::Commands()
{
auto conf = new cmds_conf_t();
conf->complete_line = &completeLine;
conf->complete_args = &completeArgs;
conf->swap_range = &swapRange;
conf->resolve_mark = &resolveMark;
conf->expand_macros = &expandMacros;
conf->expand_envvars = &expandEnvVars;
conf->post = &post;
conf->select_range = &selectRange;
conf->skip_at_beginning = &skipAtBeginning;
cmds_conf = conf;
}
Commands::~Commands()
{
delete static_cast<cmds_conf_t *>(cmds_conf);
}
bool
Commands::execute(const std::string &cmd)
{
setup();
return (vle_cmds_run(cmd.c_str()) >= 0);
}
void
Commands::setup()
{
auto conf = static_cast<cmds_conf_t *>(cmds_conf);
if(conf->inner != nullptr)
{
vle_cmds_init(/*udf=*/1, conf);
return;
}
vle_cmds_init(/*udf=*/1, conf);
std::vector<cmd_add_t> cmdsInfo;
cmdsInfo.reserve(commands.size());
for (auto &cmd : commands) {
cmd_add_t info = {};
info.name = cmd.name.c_str();
info.abbr = (cmd.abbr.empty() ? nullptr : cmd.abbr.c_str());
info.descr = cmd.descr.c_str();
info.user_data = &cmd;
info.handler = &cmdHandler;
info.min_args = cmd.minArgs;
info.max_args = (cmd.maxArgs < 0 ? NOT_DEF : cmd.maxArgs);
cmdsInfo.push_back(info);
}
vle_cmds_add(cmdsInfo.data(), cmdsInfo.size());
}
void
Commands::addCommand(Command cmd)
{
commands.push_back(std::move(cmd));
}
static int
completeLine(const char cmd_line[], void *extra_arg)
{ return 0; }
static int
completeArgs(int id, const cmd_info_t *cmd_info, int arg_pos, void *extra_arg)
{ return 0; }
static int
swapRange(void)
{ return 1; }
static int
resolveMark(char mark)
{ return -1; }
static char *
expandMacros(const char str[], int for_shell, int *usr1, int *usr2)
{ return strdup(str); }
static char *
expandEnvVars(const char *str)
{ return strdup(str); }
static void
post(int id)
{ }
static void
selectRange(int id, const cmd_info_t *cmd_info)
{ }
static int
skipAtBeginning(int id, const char *args)
{ return -1; }
// Dispatches handler invocations from the C layer.
static int
cmdHandler(const cmd_info_t *cmd_info)
{
std::vector<std::string> args;
args.reserve(cmd_info->argc);
for (int i = 0; i < cmd_info->argc; ++i) {
args.push_back(cmd_info->argv[i]);
}
auto cmd = static_cast<const Command *>(cmd_info->user_data);
cmd->handler(args);
return 0;
}
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"
Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/libvle
Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/libvle
You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a
pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master