Jim Tcl
Check-in [dc3451b724]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:linenoise: Update for optimised delete char

Update to version: https://github.com/msteveb/linenoise/commit/174a404dfa323a17852414dfc70b36976eddf6f3

Signed-off-by: Steve Bennett <steveb@workware.net.au>

Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: dc3451b72473bb06ea2416da614ce893cd61df01
User & Date: steveb@workware.net.au 2018-07-26 23:49:27
Context
2018-07-28
08:16
distclean: Remove generated tests/Makefile check-in: d8b98f3ecd user: steveb@workware.net.au tags: trunk
2018-07-26
23:49
linenoise: Update for optimised delete char

Update to version: https://github.com/msteveb/linenoise/commit/174a404dfa323a17852414dfc70b36976eddf6f3

Signed-off-by: Steve Bennett <steveb@workware.net.au> check-in: dc3451b724 user: steveb@workware.net.au tags: trunk

20:59
jim-interp.c: fix compile warning with GCC 8.1.1

GCC complains about possible truncation from snprintf() jim-interp.c: In function ‘JimInterpCommand’: jim-interp.c:164:46: warning: ‘%ld’ directive output may be truncated writing between 1 and 20 bytes into a region of size 19 [-Wformat-truncation=] snprintf(buf, sizeof(buf), "interp.handle%ld", Jim_GetId(interp)); ^~~ jim-interp.c:164:32: note: directive argument in the range [-9223372036854775807, 9223372036854775807] snprintf(buf, sizeof(buf), "interp.handle%ld", Jim_GetId(interp)); ^~~~~~~~~~~~~~~~~~ jim-interp.c:164:5: note: ‘snprintf’ output between 15 and 34 bytes into a destination of size 32 snprintf(buf, sizeof(buf), "interp.handle%ld", Jim_GetId(interp)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> check-in: 3bb8ebd082 user: borneo.antonio@gmail.com tags: trunk

Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to linenoise.c.

475
476
477
478
479
480
481
482

483
484
485
486
487
488
489
....
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524

1525
1526
1527

1528
1529

1530
1531
1532
1533
1534
1535
1536
....
1567
1568
1569
1570
1571
1572
1573

1574
1575
1576
1577




1578
















1579
1580
1581
1582
1583











1584
1585
1586
1587
1588
1589
1590
....
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615

1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
/* Structure to contain the status of the current (being edited) line */
struct current {
    stringbuf *buf; /* Current buffer. Always null terminated */
    int pos;    /* Cursor position, measured in chars */
    int cols;   /* Size of the window, in chars */
    int nrows;  /* How many rows are being used in multiline mode (>= 1) */
    int rpos;   /* The current row containing the cursor - multiline mode only */
    int availcols;  /* refreshLine() caches available cols after the prompt here */

    const char *prompt;
    stringbuf *capture; /* capture buffer, or NULL for none. Always null terminated */
    stringbuf *output;  /* used only during refreshLine() - output accumulator */
#if defined(USE_TERMIOS)
    int fd;     /* Terminal fd */
#elif defined(USE_WINCONSOLE)
    HANDLE outh; /* Console output handle */
................................................................................
    /* If we didn't see the cursor, it is at the current location */
    if (notecursor) {
        DRL("<cursor>");
        cursorcol = displaycol;
        cursorrow = displayrow;
    }

    DRL("\nafter buf: displaycol=%d, displayrow=%d, cursorcol=%d, cursorrow=%d\n\n", displaycol, displayrow, cursorcol, cursorrow);

    /* (f) show hints */
    hint = refreshShowHints(current, buf, current->cols - displaycol, 1);

    /* Remember how many many cols are available for insert optimisation */
    if (prompt == current->prompt && hint == 0) {
        current->availcols = current->cols - displaycol;

    }
    else {
        /* Can't optimise */

        current->availcols = 0;
    }


    refreshEndChars(current);

    /* (g) move the cursor to the correct place */
    cursorUp(current, displayrow - cursorrow);
    setCursorPos(current, cursorcol);

................................................................................
 * and 0 if nothing was removed
 */
static int remove_char(struct current *current, int pos)
{
    if (pos >= 0 && pos < sb_chars(current->buf)) {
        int offset = utf8_index(sb_str(current->buf), pos);
        int nbytes = utf8_index(sb_str(current->buf) + offset, 1);


        /* Note that we no longer try to optimise the remove-at-end case
         * since control characters and wide characters mess
         * up the simple count




         */
















        sb_delete(current->buf, offset, nbytes);

        if (current->pos > pos) {
            current->pos--;
        }











        return 1;
    }
    return 0;
}

/**
 * Insert 'ch' at position 'pos'
................................................................................
        /* Now we try to optimise in the simple but very common case that:
         * - we are inserting at EOL
         * - there are enough columns available
         * - no hints are being shown
         */
        if (pos == current->pos && pos == sb_chars(current->buf)) {
            int width = char_display_width(ch);
            if (current->availcols > width) {
                /* Yes, can optimise */
                current->availcols -= width;

                rc = 2;
            }
        }
        sb_insert(current->buf, offset, buf);
        if (current->pos >= pos) {
            current->pos++;
        }
        if (rc == 2) {
            if (refreshShowHints(current, sb_str(current->buf), current->availcols, 0)) {
                /* A hint needs to be shown, so can't optimise after all */
                rc = 1;
            }
            else {
                /* optimised output */
                outputChars(current, buf, n);
            }







|
>







 







|






|
>



>
|

>







 







>

<
|
|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>







 







|

|
>








|







475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
....
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
....
1571
1572
1573
1574
1575
1576
1577
1578
1579

1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
....
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
/* Structure to contain the status of the current (being edited) line */
struct current {
    stringbuf *buf; /* Current buffer. Always null terminated */
    int pos;    /* Cursor position, measured in chars */
    int cols;   /* Size of the window, in chars */
    int nrows;  /* How many rows are being used in multiline mode (>= 1) */
    int rpos;   /* The current row containing the cursor - multiline mode only */
    int colsright; /* refreshLine() cached cols for insert_char() optimisation */
    int colsleft;  /* refreshLine() cached cols for remove_char() optimisation */
    const char *prompt;
    stringbuf *capture; /* capture buffer, or NULL for none. Always null terminated */
    stringbuf *output;  /* used only during refreshLine() - output accumulator */
#if defined(USE_TERMIOS)
    int fd;     /* Terminal fd */
#elif defined(USE_WINCONSOLE)
    HANDLE outh; /* Console output handle */
................................................................................
    /* If we didn't see the cursor, it is at the current location */
    if (notecursor) {
        DRL("<cursor>");
        cursorcol = displaycol;
        cursorrow = displayrow;
    }

    DRL("\nafter buf: displaycol=%d, displayrow=%d, cursorcol=%d, cursorrow=%d\n", displaycol, displayrow, cursorcol, cursorrow);

    /* (f) show hints */
    hint = refreshShowHints(current, buf, current->cols - displaycol, 1);

    /* Remember how many many cols are available for insert optimisation */
    if (prompt == current->prompt && hint == 0) {
        current->colsright = current->cols - displaycol;
        current->colsleft = displaycol;
    }
    else {
        /* Can't optimise */
        current->colsright = 0;
        current->colsleft = 0;
    }
    DRL("\nafter hints: colsleft=%d, colsright=%d\n\n", current->colsleft, current->colsright);

    refreshEndChars(current);

    /* (g) move the cursor to the correct place */
    cursorUp(current, displayrow - cursorrow);
    setCursorPos(current, cursorcol);

................................................................................
 * and 0 if nothing was removed
 */
static int remove_char(struct current *current, int pos)
{
    if (pos >= 0 && pos < sb_chars(current->buf)) {
        int offset = utf8_index(sb_str(current->buf), pos);
        int nbytes = utf8_index(sb_str(current->buf) + offset, 1);
        int rc = 1;


        /* Now we try to optimise in the simple but very common case that:
         * - we are remove the char at EOL
         * - the buffer is not empty
         * - there are columns available to the left
         * - the char being deleted is not a wide or utf-8 character
         * - no hints are being shown
         */
        if (current->pos == pos + 1 && current->pos == sb_chars(current->buf) && pos > 0) {
#ifdef USE_UTF8
            /* Could implement utf8_prev_len() but simplest just to not optimise this case */
            char last = sb_str(current->buf)[offset];
#else
            char last = 0;
#endif
            if (current->colsleft > 0 && (last & 0x80) == 0) {
                /* Have cols on the left and not a UTF-8 char or continuation */
                /* Yes, can optimise */
                current->colsleft--;
                current->colsright++;
                rc = 2;
            }
        }

        sb_delete(current->buf, offset, nbytes);

        if (current->pos > pos) {
            current->pos--;
        }
        if (rc == 2) {
            if (refreshShowHints(current, sb_str(current->buf), current->colsright, 0)) {
                /* A hint needs to be shown, so can't optimise after all */
                rc = 1;
            }
            else {
                /* optimised output */
                outputChars(current, "\b \b", 3);
            }
        }
        return rc;
        return 1;
    }
    return 0;
}

/**
 * Insert 'ch' at position 'pos'
................................................................................
        /* Now we try to optimise in the simple but very common case that:
         * - we are inserting at EOL
         * - there are enough columns available
         * - no hints are being shown
         */
        if (pos == current->pos && pos == sb_chars(current->buf)) {
            int width = char_display_width(ch);
            if (current->colsright > width) {
                /* Yes, can optimise */
                current->colsright -= width;
                current->colsleft -= width;
                rc = 2;
            }
        }
        sb_insert(current->buf, offset, buf);
        if (current->pos >= pos) {
            current->pos++;
        }
        if (rc == 2) {
            if (refreshShowHints(current, sb_str(current->buf), current->colsright, 0)) {
                /* A hint needs to be shown, so can't optimise after all */
                rc = 1;
            }
            else {
                /* optimised output */
                outputChars(current, buf, n);
            }