Ticket #4187: grow_shrink_integer.plugin.sl

File grow_shrink_integer.plugin.sl, 3.1 KB (added by psprint, 3 years ago)

An example plugin that reads a number from the buffer, alters it and writes back

Line 
1% variable a; variable b = @a;
2
3define grow_shrink_int__get_current_or_next_number() {
4    variable pos = -1, bol_offset, eol_offset, start_digit_offset,
5        t = "", found, start_digit_seen, c1,  c2;
6
7    bol_offset = mc->cure_get_bol ();
8    eol_offset = mc->cure_get_eol ();
9
10    % Find the start of the number (a word, actually)
11    for (pos = mc->cure_cursor_offset(); pos >= bol_offset; pos--)
12    {
13        c1 = mc->cure_get_byte (pos);
14        c2 = mc->cure_get_byte (pos - 1);
15
16        if (not isdigit(c1))
17            break;
18        if (not isspace (c1) && isspace (c2))
19            break;
20    }
21
22    % Find the end of the number (a word, actually)
23    found=0;
24    start_digit_offset=0;
25    start_digit_seen=0;
26    for (; pos <= eol_offset; pos++)
27    {
28        c1 = mc->cure_get_byte (pos);
29        c2 = mc->cure_get_byte (pos + 1);
30
31        % Append the byte to the string
32        if (isdigit (c1)) {
33            if (not start_digit_seen) {
34                start_digit_seen=1;
35                start_digit_offset=pos;
36            }
37            found = 1; t += char(c1);
38        }
39
40        if (isdigit (c1) && not isdigit (c2)) {
41            found += 1;
42            break;
43        }
44    }
45
46    % Any number found?
47    % If not, return an empty string and minus one position
48    if (found == 2) {
49        % Include any minus sign
50        c1 = mc->cure_get_byte (start_digit_offset-1);
51        if (c1 == '-')
52            t = char(c1) + t;
53    }
54    return t, pos;
55}
56
57% A backend function for the two next public functions
58define grow_shrink_int__increment(direction) {
59    variable pos, cpos, number = 0;
60    variable number_str, new_number_buf;
61    variable number_len = 0, new_number_len = 0, idx;
62
63    % Get the number
64    (number_str, pos) = grow_shrink_int__get_current_or_next_number();
65    % Has been a number found?
66    if (strlen(number_str) > 0) {
67        number_len = strlen(number_str);
68        % Convert the string into integer to increment it
69        number = atoll(number_str);
70        number += (direction > 0) ? 1 : -1;
71        new_number_buf = string(number);
72        new_number_len = strlen(new_number_buf);
73
74        % Move the cursor to the found number
75        cpos = mc->cure_cursor_offset();
76        mc->cure_cursor_move (pos-cpos);
77        % Delete the existing number
78        mc->cure_delete();
79        for (idx = 0; idx < number_len-1; idx ++)
80            mc->cure_backspace();
81        % Insert updated number
82        for (idx = 0; idx < new_number_len; idx ++)
83            mc->cure_insert_ahead(new_number_buf[new_number_len-idx-1]);
84    }
85
86    % Return the updated number. Just for fun :) Maybe it'll find some use one day
87    return number;
88}
89
90% The end user function for incrementing an integer
91define grow_shrink_int__grow_int() {
92    return grow_shrink_int__increment(1);
93}
94
95% The end user function for taking 1 from an integer
96define grow_shrink_int__shrink_int() {
97    return grow_shrink_int__increment(-1);
98}
99
100% Register the default key bindings – Alt-a for grow, Alt-x for shrink.
101mc->editor_map_key_to_func("GrowInteger", "alt-a", "grow_shrink_int__grow_int");
102mc->editor_map_key_to_func("ShrinkInteger", "alt-x", "grow_shrink_int__shrink_int");