4 #include "jimautoconf.h"
11 #ifdef HAVE_SYS_STAT_H
14 #include "linenoise.h"
16 #define MAX_LINE_LEN 512
20 * Returns an allocated line, or NULL if EOF.
22 char *Jim_HistoryGetline(const char *prompt
)
25 return linenoise(prompt
);
28 char *line
= malloc(MAX_LINE_LEN
);
30 fputs(prompt
, stdout
);
33 if (fgets(line
, MAX_LINE_LEN
, stdin
) == NULL
) {
38 if (len
&& line
[len
- 1] == '\n') {
45 void Jim_HistoryLoad(const char *filename
)
48 linenoiseHistoryLoad(filename
);
52 void Jim_HistoryAdd(const char *line
)
55 linenoiseHistoryAdd(line
);
59 void Jim_HistorySave(const char *filename
)
64 /* Just u=rw, but note that this is only effective for newly created files */
65 mask
= umask(S_IXUSR
| S_IRWXG
| S_IRWXO
);
67 linenoiseHistorySave(filename
);
74 void Jim_HistoryShow(void)
77 /* built-in history command */
80 char **history
= linenoiseHistory(&len
);
81 for (i
= 0; i
< len
; i
++) {
82 printf("%4d %s\n", i
+ 1, history
[i
]);
88 struct JimCompletionInfo
{
93 void JimCompletionCallback(const char *prefix
, linenoiseCompletions
*comp
, void *userdata
)
95 struct JimCompletionInfo
*info
= (struct JimCompletionInfo
*)userdata
;
98 objv
[0] = info
->command
;
99 objv
[1] = Jim_NewStringObj(info
->interp
, prefix
, -1);
101 int ret
= Jim_EvalObjVector(info
->interp
, 2, objv
);
103 /* XXX: Consider how best to handle errors here. bgerror? */
106 Jim_Obj
*listObj
= Jim_GetResult(info
->interp
);
107 int len
= Jim_ListLength(info
->interp
, listObj
);
108 for (i
= 0; i
< len
; i
++) {
109 linenoiseAddCompletion(comp
, Jim_String(Jim_ListGetIndex(info
->interp
, listObj
, i
)));
115 int Jim_InteractivePrompt(Jim_Interp
*interp
)
117 int retcode
= JIM_OK
;
118 char *history_file
= NULL
;
121 struct JimCompletionInfo compinfo
;
123 home
= getenv("HOME");
124 if (home
&& isatty(STDIN_FILENO
)) {
125 int history_len
= strlen(home
) + sizeof("/.jim_history");
126 history_file
= Jim_Alloc(history_len
);
127 snprintf(history_file
, history_len
, "%s/.jim_history", home
);
128 Jim_HistoryLoad(history_file
);
131 compinfo
.interp
= interp
;
132 compinfo
.command
= Jim_NewStringObj(interp
, "tcl::autocomplete", -1);
133 Jim_IncrRefCount(compinfo
.command
);
135 /* Register a callback function for tab-completion. */
136 linenoiseSetCompletionCallback(JimCompletionCallback
, &compinfo
);
139 printf("Welcome to Jim version %d.%d\n",
140 JIM_VERSION
/ 100, JIM_VERSION
% 100);
141 Jim_SetVariableStrWithStr(interp
, JIM_INTERACTIVE
, "1");
144 Jim_Obj
*scriptObjPtr
;
149 if (retcode
!= JIM_OK
) {
150 const char *retcodestr
= Jim_ReturnCode(retcode
);
152 if (*retcodestr
== '?') {
153 snprintf(prompt
, sizeof(prompt
) - 3, "[%d] . ", retcode
);
156 snprintf(prompt
, sizeof(prompt
) - 3, "[%s] . ", retcodestr
);
160 strcpy(prompt
, ". ");
163 scriptObjPtr
= Jim_NewStringObj(interp
, "", 0);
164 Jim_IncrRefCount(scriptObjPtr
);
169 line
= Jim_HistoryGetline(prompt
);
171 if (errno
== EINTR
) {
174 Jim_DecrRefCount(interp
, scriptObjPtr
);
178 if (Jim_Length(scriptObjPtr
) != 0) {
179 /* Line continuation */
180 Jim_AppendString(interp
, scriptObjPtr
, "\n", 1);
182 Jim_AppendString(interp
, scriptObjPtr
, line
, -1);
184 if (Jim_ScriptIsComplete(interp
, scriptObjPtr
, &state
))
187 snprintf(prompt
, sizeof(prompt
), "%c> ", state
);
190 if (strcmp(Jim_String(scriptObjPtr
), "h") == 0) {
191 /* built-in history command */
193 Jim_DecrRefCount(interp
, scriptObjPtr
);
197 Jim_HistoryAdd(Jim_String(scriptObjPtr
));
199 Jim_HistorySave(history_file
);
202 retcode
= Jim_EvalObj(interp
, scriptObjPtr
);
203 Jim_DecrRefCount(interp
, scriptObjPtr
);
205 if (retcode
== JIM_EXIT
) {
208 if (retcode
== JIM_ERR
) {
209 Jim_MakeErrorMessage(interp
);
211 result
= Jim_GetString(Jim_GetResult(interp
), &reslen
);
213 printf("%s\n", result
);
217 Jim_Free(history_file
);
220 Jim_DecrRefCount(interp
, compinfo
.command
);
221 linenoiseSetCompletionCallback(NULL
, NULL
);