src/feature/editline/cli-el-backend.c (view raw)
1/* Copyright (c) 2013-2014 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "cli-el-backend.h"
7
8#include "core/version.h"
9
10#include <signal.h>
11
12static struct CLIDebugger* _activeDebugger;
13
14static char* _prompt(EditLine* el) {
15 UNUSED(el);
16 return "> ";
17}
18
19static void _breakIntoDefault(int signal) {
20 UNUSED(signal);
21 mDebuggerEnter(&_activeDebugger->d, DEBUGGER_ENTER_MANUAL, 0);
22}
23
24static unsigned char _tabComplete(EditLine* elstate, int ch) {
25 UNUSED(ch);
26 const LineInfo* li = el_line(elstate);
27 if (!li->buffer[0]) {
28 return CC_ERROR;
29 }
30
31 struct CLIDebuggerEditLineBackend* elbe;
32 el_get(elstate, EL_CLIENTDATA, &elbe);
33 // TODO: not always true
34 if (CLIDebuggerTabComplete(elbe->d.p, li->buffer, true, li->cursor - li->buffer)) {
35 return CC_REDISPLAY;
36 }
37 return CC_ERROR;
38}
39
40ATTRIBUTE_FORMAT(printf, 2, 3)
41void _CLIDebuggerEditLinePrintf(struct CLIDebuggerBackend* be, const char* fmt, ...) {
42 UNUSED(be);
43 va_list args;
44 va_start(args, fmt);
45 vprintf(fmt, args);
46 va_end(args);
47}
48
49void _CLIDebuggerEditLineInit(struct CLIDebuggerBackend* be) {
50 struct CLIDebuggerEditLineBackend* elbe = (struct CLIDebuggerEditLineBackend*) be;
51 // TODO: get argv[0]
52 elbe->elstate = el_init(binaryName, stdin, stdout, stderr);
53 el_set(elbe->elstate, EL_PROMPT, _prompt);
54 el_set(elbe->elstate, EL_EDITOR, "emacs");
55
56 el_set(elbe->elstate, EL_CLIENTDATA, elbe);
57 el_set(elbe->elstate, EL_ADDFN, "tab-complete", "Tab completion", _tabComplete);
58 el_set(elbe->elstate, EL_BIND, "\t", "tab-complete", 0);
59 elbe->histate = history_init();
60 HistEvent ev;
61 history(elbe->histate, &ev, H_SETSIZE, 200);
62 el_set(elbe->elstate, EL_HIST, history, elbe->histate);
63 _activeDebugger = be->p;
64 signal(SIGINT, _breakIntoDefault);
65}
66
67void _CLIDebuggerEditLineDeinit(struct CLIDebuggerBackend* be) {
68 struct CLIDebuggerEditLineBackend* elbe = (struct CLIDebuggerEditLineBackend*) be;
69 history_end(elbe->histate);
70 el_end(elbe->elstate);
71}
72
73const char* _CLIDebuggerEditLineReadLine(struct CLIDebuggerBackend* be, size_t* len) {
74 struct CLIDebuggerEditLineBackend* elbe = (struct CLIDebuggerEditLineBackend*) be;
75 int count;
76 *len = 0;
77 const char* line = el_gets(elbe->elstate, &count);
78 if (line && count >= 1) {
79 // Crop off newline
80 *len = (size_t) count - 1;
81 }
82 return line;
83}
84void _CLIDebuggerEditLineLineAppend(struct CLIDebuggerBackend* be, const char* line) {
85 struct CLIDebuggerEditLineBackend* elbe = (struct CLIDebuggerEditLineBackend*) be;
86 el_insertstr(elbe->elstate, line);
87}
88
89const char* _CLIDebuggerEditLineHistoryLast(struct CLIDebuggerBackend* be, size_t* len) {
90 struct CLIDebuggerEditLineBackend* elbe = (struct CLIDebuggerEditLineBackend*) be;
91 HistEvent ev;
92 if (history(elbe->histate, &ev, H_FIRST) < 0) {
93 *len = 0;
94 return NULL;
95 }
96 const char* newline = strchr(ev.str, '\n');
97 if (!newline) {
98 *len = strlen(ev.str);
99 } else {
100 *len = newline - ev.str;
101 }
102
103 return ev.str;
104}
105
106void _CLIDebuggerEditLineHistoryAppend(struct CLIDebuggerBackend* be, const char* line) {
107 struct CLIDebuggerEditLineBackend* elbe = (struct CLIDebuggerEditLineBackend*) be;
108 HistEvent ev;
109 history(elbe->histate, &ev, H_ENTER, line);
110}
111
112struct CLIDebuggerBackend* CLIDebuggerEditLineBackendCreate(void) {
113 struct CLIDebuggerEditLineBackend* elbe = malloc(sizeof(*elbe));
114 elbe->d.printf = _CLIDebuggerEditLinePrintf;
115 elbe->d.init = _CLIDebuggerEditLineInit;
116 elbe->d.deinit = _CLIDebuggerEditLineDeinit;
117 elbe->d.readline = _CLIDebuggerEditLineReadLine;
118 elbe->d.lineAppend = _CLIDebuggerEditLineLineAppend;
119 elbe->d.historyLast = _CLIDebuggerEditLineHistoryLast;
120 elbe->d.historyAppend = _CLIDebuggerEditLineHistoryAppend;
121 return &elbe->d;
122}