@@ -961,6 +961,10 @@ Object copy_object(Object obj)
961
961
962
962
case kObjectTypeDictionary:
963
963
return DICTIONARY_OBJ(copy_dictionary(obj.data.dictionary));
964
+
965
+
case kObjectTypeLuaRef:
966
+
return LUAREF_OBJ(api_new_luaref(obj.data.luaref));
967
+
964
968
default:
965
969
abort();
966
970
}
@@ -1342,3 +1346,184 @@ const char *get_default_stl_hl(win_T *wp)
1342
1346
return "StatusLineNC";
1343
1347
}
1344
1348
}
1349
+
1350
+
void add_user_command(String name, Object command, Dict(user_command) *opts, int flags, Error *err)
1351
+
{
1352
+
uint32_t argt = 0;
1353
+
long def = -1;
1354
+
cmd_addr_T addr_type_arg = ADDR_NONE;
1355
+
int compl = EXPAND_NOTHING;
1356
+
char *compl_arg = NULL;
1357
+
char *rep = NULL;
1358
+
LuaRef luaref = LUA_NOREF;
1359
+
LuaRef compl_luaref = LUA_NOREF;
1360
+
1361
+
if (HAS_KEY(opts->range) && HAS_KEY(opts->count)) {
1362
+
api_set_error(err, kErrorTypeValidation, "'range' and 'count' are mutually exclusive");
1363
+
goto err;
1364
+
}
1365
+
1366
+
if (opts->nargs.type == kObjectTypeInteger) {
1367
+
switch (opts->nargs.data.integer) {
1368
+
case 0:
1369
+
// Default value, nothing to do
1370
+
break;
1371
+
case 1:
1372
+
argt |= EX_EXTRA | EX_NOSPC | EX_NEEDARG;
1373
+
break;
1374
+
default:
1375
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'nargs'");
1376
+
goto err;
1377
+
}
1378
+
} else if (opts->nargs.type == kObjectTypeString) {
1379
+
if (opts->nargs.data.string.size > 1) {
1380
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'nargs'");
1381
+
goto err;
1382
+
}
1383
+
1384
+
switch (opts->nargs.data.string.data[0]) {
1385
+
case '*':
1386
+
argt |= EX_EXTRA;
1387
+
break;
1388
+
case '?':
1389
+
argt |= EX_EXTRA | EX_NOSPC;
1390
+
break;
1391
+
case '+':
1392
+
argt |= EX_EXTRA | EX_NEEDARG;
1393
+
break;
1394
+
default:
1395
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'nargs'");
1396
+
goto err;
1397
+
}
1398
+
} else if (HAS_KEY(opts->nargs)) {
1399
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'nargs'");
1400
+
goto err;
1401
+
}
1402
+
1403
+
if (HAS_KEY(opts->complete) && !argt) {
1404
+
api_set_error(err, kErrorTypeValidation, "'complete' used without 'nargs'");
1405
+
goto err;
1406
+
}
1407
+
1408
+
if (opts->range.type == kObjectTypeBoolean) {
1409
+
if (opts->range.data.boolean) {
1410
+
argt |= EX_RANGE;
1411
+
addr_type_arg = ADDR_LINES;
1412
+
}
1413
+
} else if (opts->range.type == kObjectTypeString) {
1414
+
if (opts->range.data.string.data[0] == '%' && opts->range.data.string.size == 1) {
1415
+
argt |= EX_RANGE | EX_DFLALL;
1416
+
addr_type_arg = ADDR_LINES;
1417
+
} else {
1418
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'range'");
1419
+
goto err;
1420
+
}
1421
+
} else if (opts->range.type == kObjectTypeInteger) {
1422
+
argt |= EX_RANGE | EX_ZEROR;
1423
+
def = opts->range.data.integer;
1424
+
addr_type_arg = ADDR_LINES;
1425
+
} else if (HAS_KEY(opts->range)) {
1426
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'range'");
1427
+
goto err;
1428
+
}
1429
+
1430
+
if (opts->count.type == kObjectTypeBoolean) {
1431
+
if (opts->count.data.boolean) {
1432
+
argt |= EX_COUNT | EX_ZEROR | EX_RANGE;
1433
+
addr_type_arg = ADDR_OTHER;
1434
+
def = 0;
1435
+
}
1436
+
} else if (opts->count.type == kObjectTypeInteger) {
1437
+
argt |= EX_COUNT | EX_ZEROR | EX_RANGE;
1438
+
addr_type_arg = ADDR_OTHER;
1439
+
def = opts->count.data.integer;
1440
+
} else if (HAS_KEY(opts->count)) {
1441
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'count'");
1442
+
goto err;
1443
+
}
1444
+
1445
+
if (opts->addr.type == kObjectTypeString) {
1446
+
if (parse_addr_type_arg((char_u *)opts->addr.data.string.data, (int)opts->addr.data.string.size,
1447
+
&addr_type_arg) != OK) {
1448
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'addr'");
1449
+
goto err;
1450
+
}
1451
+
1452
+
if (addr_type_arg != ADDR_LINES) {
1453
+
argt |= EX_ZEROR;
1454
+
}
1455
+
} else if (HAS_KEY(opts->addr)) {
1456
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'addr'");
1457
+
goto err;
1458
+
}
1459
+
1460
+
if (api_object_to_bool(opts->bang, "bang", false, err)) {
1461
+
argt |= EX_BANG;
1462
+
} else if (ERROR_SET(err)) {
1463
+
goto err;
1464
+
}
1465
+
1466
+
if (api_object_to_bool(opts->bar, "bar", false, err)) {
1467
+
argt |= EX_TRLBAR;
1468
+
} else if (ERROR_SET(err)) {
1469
+
goto err;
1470
+
}
1471
+
1472
+
1473
+
if (api_object_to_bool(opts->register_, "register", false, err)) {
1474
+
argt |= EX_REGSTR;
1475
+
} else if (ERROR_SET(err)) {
1476
+
goto err;
1477
+
}
1478
+
1479
+
bool force = api_object_to_bool(opts->force, "force", false, err);
1480
+
if (ERROR_SET(err)) {
1481
+
goto err;
1482
+
}
1483
+
1484
+
if (opts->complete.type == kObjectTypeLuaRef) {
1485
+
compl = EXPAND_USER_LUA;
1486
+
compl_luaref = api_new_luaref(opts->complete.data.luaref);
1487
+
} else if (opts->complete.type == kObjectTypeString) {
1488
+
if (parse_compl_arg((char_u *)opts->complete.data.string.data,
1489
+
(int)opts->complete.data.string.size, &compl, &argt,
1490
+
(char_u **)&compl_arg) != OK) {
1491
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'complete'");
1492
+
goto err;
1493
+
}
1494
+
} else if (HAS_KEY(opts->complete)) {
1495
+
api_set_error(err, kErrorTypeValidation, "Invalid value for 'complete'");
1496
+
goto err;
1497
+
}
1498
+
1499
+
switch (command.type) {
1500
+
case kObjectTypeLuaRef:
1501
+
luaref = api_new_luaref(command.data.luaref);
1502
+
if (opts->desc.type == kObjectTypeString) {
1503
+
rep = opts->desc.data.string.data;
1504
+
} else {
1505
+
snprintf((char *)IObuff, IOSIZE, "<Lua function %d>", luaref);
1506
+
rep = (char *)IObuff;
1507
+
}
1508
+
break;
1509
+
case kObjectTypeString:
1510
+
rep = command.data.string.data;
1511
+
break;
1512
+
default:
1513
+
api_set_error(err, kErrorTypeValidation, "'command' must be a string or Lua function");
1514
+
goto err;
1515
+
}
1516
+
1517
+
if (uc_add_command((char_u *)name.data, name.size, (char_u *)rep, argt, def, flags,
1518
+
compl, (char_u *)compl_arg, compl_luaref, addr_type_arg, luaref,
1519
+
force) != OK) {
1520
+
api_set_error(err, kErrorTypeException, "Failed to create user command");
1521
+
goto err;
1522
+
}
1523
+
1524
+
return;
1525
+
1526
+
err:
1527
+
NLUA_CLEAR_REF(luaref);
1528
+
NLUA_CLEAR_REF(compl_luaref);
1529
+
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4