Skip to content

Commit 0abfcc3

Browse files
lePicimichalvasko
authored andcommitted
yanglint FEATURE multiline for interactive mode
The tcl-tests needed to be modified because ANSI escape codes are sent differently.
1 parent ab1b5f9 commit 0abfcc3

File tree

5 files changed

+44
-13
lines changed

5 files changed

+44
-13
lines changed

tests/tool_i.tcl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,7 @@ proc ly_completion {input output} {
135135
global prompt
136136

137137
send -- "${input}\t"
138-
# expecting echoing input, output and 10 terminal control characters
139-
expect -re "^${input}\r${prompt}${output}.*\r.*$"
138+
expect -re "${input}${output}"
140139
}
141140

142141
# Send a completion request and check if the anchored regex hint options match.
@@ -146,11 +145,13 @@ proc ly_hint {input prev_input hints} {
146145
set output {}
147146
foreach i $hints {
148147
# each element might have some number of spaces and CRLF around it
149-
append output "${i} *(?:\\r\\n)?"
148+
append output "${i} *(\\r\\n)?"
150149
}
150+
set termcode1 "\r\\u001b\\\[0K"
151+
set termcode2 ".*"
151152

152153
send -- "${input}\t"
153154
# expecting the hints, previous input from which the hints were generated
154155
# and some number of terminal control characters
155-
expect -re "${output}\r${prompt}${prev_input}.*\r.*$"
156+
expect -re "${output}${termcode1}${prompt}${prev_input}${termcode2}"
156157
}

tests/yanglint/interactive/completion.test

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ test completion_hints_ietf_ip {Completion and hints for ietf-ip.yang} {
1212
ly_cmd "add $mdir/ietf-ip.yang"
1313

1414
# completion and hint
15-
ly_completion "print -f info -P " "print -f info -P /ietf-"
15+
ly_completion "print -f info -P " "/ietf-"
1616

1717
set hints {"/ietf-yang-schema-mount:schema-mounts" "/ietf-interfaces:interfaces" "/ietf-interfaces:interfaces-state"}
1818
ly_hint "" "print -f info -P /ietf-" $hints
1919

2020
# double completion
21-
ly_completion "i" "print -f info -P /ietf-interfaces:interfaces"
22-
ly_completion "/" "print -f info -P /ietf-interfaces:interfaces/interface"
21+
ly_completion "i" "nterfaces:interfaces"
22+
ly_completion "/" "interface"
23+
# current cli: print -f info -P /ietf-interfaces:interfaces/interface
2324

2425
# a lot of hints
2526
set hints {"/ietf-interfaces:interfaces/interface"
@@ -31,16 +32,20 @@ test completion_hints_ietf_ip {Completion and hints for ietf-ip.yang} {
3132
ly_hint "" "print -f info -P /ietf-interfaces:interfaces/interface" $hints
3233

3334
# double tab
34-
ly_completion "/i" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv"
35-
ly_completion "4" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4"
35+
ly_completion "/i" "etf-ip:ipv"
36+
# current cli: print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv
37+
ly_completion "4" ""
38+
# current cli: print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4
39+
3640
set hints { "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/enabled"
3741
"/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/forwarding" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/mtu"
3842
"/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/neighbor"
3943
}
40-
ly_hint "\t" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv" $hints
44+
ly_hint "\t" "print -f info -P /ietf-interfaces:interfaces/interface" $hints
4145

4246
# no more completion
43-
ly_completion "/e" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4/enabled "
47+
ly_completion "/e" "nabled "
48+
# current cli: print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4/enabled
4449
}}
4550

4651
# Note that somehow a command is automatically sent again (\t\t replaced by \r) after the hints.

tools/lint/linenoise/linenoise.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,12 @@ static size_t columnPos(const char *buf, size_t buf_len, size_t pos) {
245245
static size_t columnPosForMultiLine(const char *buf, size_t buf_len, size_t pos, size_t cols, size_t ini_pos) {
246246
size_t ret = 0;
247247
size_t colwid = ini_pos;
248+
size_t len;
248249

249250
size_t off = 0;
250251
while (off < buf_len) {
251252
size_t col_len;
252-
size_t len = nextCharLen(buf,buf_len,off,&col_len);
253+
len = nextCharLen(buf,buf_len,off,&col_len);
253254

254255
int dif = (int)(colwid + col_len) - (int)cols;
255256
if (dif > 0) {
@@ -799,7 +800,7 @@ static void refreshSingleLine(struct linenoiseState *l, int flags) {
799800
static void refreshMultiLine(struct linenoiseState *l, int flags) {
800801
char seq[64];
801802
size_t pcollen = promptTextColumnLen(l->prompt,strlen(l->prompt));
802-
int colpos = columnPosForMultiLine(l->buf, l->len, l->len, l->cols, pcollen);
803+
size_t colpos = columnPosForMultiLine(l->buf, l->len, l->len, l->cols, pcollen);
803804
int colpos2; /* cursor column position. */
804805
int rows = (pcollen+colpos+l->cols-1)/l->cols; /* rows used by current buf. */
805806
int rpos = (pcollen+l->oldcolpos+l->cols)/l->cols; /* cursor relative row. */
@@ -815,6 +816,23 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
815816
* going to the last row. */
816817
abInit(&ab);
817818

819+
if ((l->oldcollen < l->len) && // some character was added
820+
(l->pos == l->len) && // at the end of the line
821+
(l->pos <= l->cols) && // no multiline break
822+
(l->prev_history_index == l->history_index) // no buffer change based on history
823+
) {
824+
/* Ignore flags and just add one character.
825+
* This code was added because redundant ANSI escape codes make tcl-tests incapable.
826+
*/
827+
abAppend(&ab,l->buf + l->oldcollen,strlen(l->buf) - l->oldcollen);
828+
l->oldcolpos = colpos;
829+
l->oldcollen = l->len;
830+
if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */
831+
abFree(&ab);
832+
l->prev_history_index = l->history_index;
833+
return;
834+
}
835+
818836
if (flags & REFRESH_CLEAN) {
819837
if (old_rows-rpos > 0) {
820838
lndebug("go down %d", old_rows-rpos);
@@ -890,6 +908,8 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
890908

891909
lndebug("\n");
892910
l->oldcolpos = colpos2;
911+
l->oldcollen = l->len;
912+
l->prev_history_index = l->history_index;
893913

894914
if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */
895915
abFree(&ab);
@@ -1096,6 +1116,7 @@ int linenoiseEditStart(struct linenoiseState *l, int stdin_fd, int stdout_fd, ch
10961116
l->prompt = prompt;
10971117
l->plen = strlen(prompt);
10981118
l->oldcolpos = l->pos = 0;
1119+
l->oldcollen = 0;
10991120
l->len = 0;
11001121

11011122
/* Enter raw mode. */
@@ -1104,6 +1125,7 @@ int linenoiseEditStart(struct linenoiseState *l, int stdin_fd, int stdout_fd, ch
11041125
l->cols = getColumns(stdin_fd, stdout_fd);
11051126
l->oldrows = 0;
11061127
l->history_index = 0;
1128+
l->prev_history_index = 0;
11071129

11081130
/* Buffer starts empty. */
11091131
l->buf[0] = '\0';

tools/lint/linenoise/linenoise.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@ struct linenoiseState {
6262
size_t plen; /* Prompt length. */
6363
size_t pos; /* Current cursor position. */
6464
size_t oldcolpos; /* Previous refresh cursor column position. */
65+
size_t oldcollen; /* Previous length of buffer. */
6566
size_t len; /* Current edited line length. */
6667
size_t cols; /* Number of columns in terminal. */
6768
size_t oldrows; /* Rows used by last refrehsed line (multiline mode) */
6869
int history_index; /* The history index we are currently editing. */
70+
int prev_history_index; /* Previous history index. */
6971
};
7072

7173
typedef struct linenoiseCompletions {

tools/lint/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ main(int argc, char *argv[])
5555
/* continue in interactive mode */
5656
linenoiseSetCompletionCallback(complete_cmd);
5757
linenoiseSetEncodingFunctions(linenoiseUtf8PrevCharLen, linenoiseUtf8NextCharLen, linenoiseUtf8ReadCode);
58+
linenoiseSetMultiLine(1);
5859
load_config();
5960

6061
if (ly_ctx_new(NULL, YL_DEFAULT_CTX_OPTIONS, &ctx)) {

0 commit comments

Comments
 (0)