comparison src/mark.c @ 20615:8eed1e9389bb v8.2.0861

patch 8.2.0861: cannot easily get all the current marks Commit: https://github.com/vim/vim/commit/cfb4b47de08e4437c692d382067dc1692cd83c23 Author: Bram Moolenaar <Bram@vim.org> Date: Sun May 31 15:41:57 2020 +0200 patch 8.2.0861: cannot easily get all the current marks Problem: Cannot easily get all the current marks. Solution: Add getmarklist(). (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/6032)
author Bram Moolenaar <Bram@vim.org>
date Sun, 31 May 2020 15:45:04 +0200
parents de2d1820215a
children 3e36a51ff152
comparison
equal deleted inserted replaced
20614:78caf677340d 20615:8eed1e9389bb
1410 xfmark_T * 1410 xfmark_T *
1411 get_namedfm(void) 1411 get_namedfm(void)
1412 { 1412 {
1413 return namedfm; 1413 return namedfm;
1414 } 1414 }
1415
1416 #if defined(FEAT_EVAL) || defined(PROTO)
1417 /*
1418 * Add information about mark 'mname' to list 'l'
1419 */
1420 static int
1421 add_mark(list_T *l, char_u *mname, pos_T *pos, int bufnr, char_u *fname)
1422 {
1423 dict_T *d;
1424 list_T *lpos;
1425
1426 if (pos->lnum <= 0)
1427 return OK;
1428
1429 d = dict_alloc();
1430 if (d == NULL)
1431 return FAIL;
1432
1433 if (list_append_dict(l, d) == FAIL)
1434 {
1435 dict_unref(d);
1436 return FAIL;
1437 }
1438
1439 lpos = list_alloc();
1440 if (lpos == NULL)
1441 return FAIL;
1442
1443 list_append_number(lpos, bufnr);
1444 list_append_number(lpos, pos->lnum);
1445 list_append_number(lpos, pos->col);
1446 list_append_number(lpos, pos->coladd);
1447
1448 if (dict_add_string(d, "mark", mname) == FAIL
1449 || dict_add_list(d, "pos", lpos) == FAIL
1450 || (fname != NULL && dict_add_string(d, "file", fname) == FAIL))
1451 return FAIL;
1452
1453 return OK;
1454 }
1455
1456 /*
1457 * Get information about marks local to a buffer.
1458 */
1459 static void
1460 get_buf_local_marks(buf_T *buf, list_T *l)
1461 {
1462 char_u mname[3] = "' ";
1463 int i;
1464
1465 // Marks 'a' to 'z'
1466 for (i = 0; i < NMARKS; ++i)
1467 {
1468 mname[1] = 'a' + i;
1469 add_mark(l, mname, &buf->b_namedm[i], buf->b_fnum, NULL);
1470 }
1471
1472 // Mark '' is a window local mark and not a buffer local mark
1473 add_mark(l, (char_u *)"''", &curwin->w_pcmark, curbuf->b_fnum, NULL);
1474
1475 add_mark(l, (char_u *)"'\"", &buf->b_last_cursor, buf->b_fnum, NULL);
1476 add_mark(l, (char_u *)"'[", &buf->b_op_start, buf->b_fnum, NULL);
1477 add_mark(l, (char_u *)"']", &buf->b_op_end, buf->b_fnum, NULL);
1478 add_mark(l, (char_u *)"'^", &buf->b_last_insert, buf->b_fnum, NULL);
1479 add_mark(l, (char_u *)"'.", &buf->b_last_change, buf->b_fnum, NULL);
1480 add_mark(l, (char_u *)"'<", &buf->b_visual.vi_start, buf->b_fnum, NULL);
1481 add_mark(l, (char_u *)"'>", &buf->b_visual.vi_end, buf->b_fnum, NULL);
1482 }
1483
1484 /*
1485 * Get information about global marks ('A' to 'Z' and '0' to '9')
1486 */
1487 static void
1488 get_global_marks(list_T *l)
1489 {
1490 char_u mname[3] = "' ";
1491 int i;
1492 char_u *name;
1493
1494 // Marks 'A' to 'Z' and '0' to '9'
1495 for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
1496 {
1497 if (namedfm[i].fmark.fnum != 0)
1498 name = buflist_nr2name(namedfm[i].fmark.fnum, TRUE, TRUE);
1499 else
1500 name = namedfm[i].fname;
1501 if (name != NULL)
1502 {
1503 mname[1] = i >= NMARKS ? i - NMARKS + '0' : i + 'A';
1504 add_mark(l, mname, &namedfm[i].fmark.mark,
1505 namedfm[i].fmark.fnum, name);
1506 if (namedfm[i].fmark.fnum != 0)
1507 vim_free(name);
1508 }
1509 }
1510 }
1511
1512 /*
1513 * getmarklist() function
1514 */
1515 void
1516 f_getmarklist(typval_T *argvars, typval_T *rettv)
1517 {
1518 buf_T *buf = NULL;
1519
1520 if (rettv_list_alloc(rettv) != OK)
1521 return;
1522
1523 if (argvars[0].v_type == VAR_UNKNOWN)
1524 {
1525 get_global_marks(rettv->vval.v_list);
1526 return;
1527 }
1528
1529 buf = tv_get_buf(&argvars[0], FALSE);
1530 if (buf == NULL)
1531 return;
1532
1533 get_buf_local_marks(buf, rettv->vval.v_list);
1534 }
1535 #endif