3 * VIM - Vi IMproved by Bram Moolenaar
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
11 * Tcl extensions by Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
12 * Last modification: Wed May 10 21:28:44 CEST 2000
13 * Requires Tcl 8.0 or higher.
16 * ::vim::current(buffer) # Name of buffer command for current buffer.
17 * ::vim::current(window) # Name of window command for current window.
18 * ::vim::range(start) # Start of current range (line number).
19 * ::vim::range(end) # End of current range (line number).
20 * ::vim::lbase # Start of line/column numbers (1 or 0).
23 * ::vim::command {cmd} # Execute ex command {cmd}.
24 * ::vim::option {opt} [val] # Get/Set option {opt}.
25 * ::vim::expr {expr} # Evaluate {expr} using vim's evaluator.
26 * ::vim::beep # Guess.
28 * set buf [::vim::buffer {n}] # Create Tcl command for buffer N.
29 * set bl [::vim::buffer list] # Get list of Tcl commands of all buffers.
30 * ::vim::buffer exists {n} # True if buffer {n} exists.
32 * set wl [::vim::window list] # Get list of Tcl commands of all windows.
34 * set n [$win height] # Report window height.
35 * $win height {n} # Set window height to {n}.
36 * array set pos [$win cursor] # Get cursor position.
37 * $win cursor {row} {col} # Set cursor position.
38 * $win cursor pos # Set cursor position from array var "pos"
39 * $win delcmd {cmd} # Register callback command for closed window.
40 * $win option {opt} [val] # Get/Set vim option in context of $win.
41 * $win command {cmd} # Execute ex command in context of $win.
42 * $win expr {expr} # Evaluate vim expression in context of $win.
43 * set buf [$win buffer] # Create Tcl command for window's buffer.
45 * $buf name # Reports file name in buffer.
46 * $buf number # Reports buffer number.
47 * set l [$buf get {n}] # Get buffer line {n} as a string.
48 * set L [$buf get {n} {m}] # Get lines {n} through {m} as a list.
49 * $buf count # Reports number of lines in buffer.
50 * $buf last # Reports number of last line in buffer.
51 * $buf delete {n} # Delete line {n}.
52 * $buf delete {n} {m} # Delete lines {n} through {m}.
53 * $buf set {n} {l} # Set line {n} to string {l}.
54 * $buf set {n} {m} {L} # Set lines {n} through {m} from list {L}.
55 * # Delete/inserts lines as appropriate.
56 * $buf option {opt} [val] # Get/Set vim option in context of $buf.
57 * $buf command {cmd} # Execute ex command in context of $buf
58 * $buf expr {cmd} # Evaluate vim expression in context of $buf.
59 * array set pos [$buf mark {m}] # Get position of mark.
60 * $buf append {n} {str} # Append string {str} to buffer,after line {n}.
61 * $buf insert {n} {str} # Insert string {str} in buffer as line {n}.
62 * $buf delcmd {cmd} # Register callback command for deleted buffer.
63 * set wl [$buf windows] # Get list of Tcl commands for all windows of
66 * ::vim::buffer new # create new buffer + Tcl command
70 #undef EXTERN /* tcl.h defines it too */
73 # define USE_TCL_STUBS /* use tcl's stubs mechanism */
83 int range_start
, range_end
;
85 char *curbuf
, *curwin
;
88 static tcl_info tclinfo
= { NULL
, 0, 0, 0, NULL
, NULL
};
90 #define VAR_RANGE1 "::vim::range(start)"
91 #define VAR_RANGE2 "::vim::range(begin)"
92 #define VAR_RANGE3 "::vim::range(end)"
93 #define VAR_CURBUF "::vim::current(buffer)"
94 #define VAR_CURWIN "::vim::current(window)"
95 #define VAR_LBASE "::vim::lbase"
96 #define VAR_CURLINE "line"
97 #define VAR_CURLNUM "lnum"
98 #define VARNAME_SIZE 64
100 #define row2tcl(x) ((x) - (tclinfo.lbase==0))
101 #define row2vim(x) ((x) + (tclinfo.lbase==0))
102 #define col2tcl(x) ((x) + (tclinfo.lbase!=0))
103 #define col2vim(x) ((x) - (tclinfo.lbase!=0))
106 #define VIMOUT ((ClientData)1)
107 #define VIMERR ((ClientData)2)
109 /* This appears to be new in Tcl 8.4. */
115 * List of Tcl interpreters who reference a vim window or buffer.
116 * Each buffer and window has it's own list in the w_tcl_ref or b_tcl_ref
117 * struct member. We need this because Tcl can create sub-interpreters with
118 * the "interp" command, and each interpreter can reference all windows and
126 Tcl_Command cmd
; /* Tcl command that represents this object */
127 Tcl_Obj
*delcmd
; /* Tcl command to call when object is being del. */
128 void *vimobj
; /* Vim window or buffer (win_T* or buf_T*) */
130 static char * tclgetbuffer
_ANSI_ARGS_((Tcl_Interp
*interp
, buf_T
*buf
));
131 static char * tclgetwindow
_ANSI_ARGS_((Tcl_Interp
*interp
, win_T
*win
));
132 static int tclsetdelcmd
_ANSI_ARGS_((Tcl_Interp
*interp
, struct ref
*reflist
, void *vimobj
, Tcl_Obj
*delcmd
));
133 static int tclgetlinenum
_ANSI_ARGS_ ((Tcl_Interp
*interp
, Tcl_Obj
*obj
, int *valueP
, buf_T
*buf
));
134 static win_T
*tclfindwin
_ANSI_ARGS_ ((buf_T
*buf
));
135 static int tcldoexcommand
_ANSI_ARGS_ ((Tcl_Interp
*interp
, int objc
, Tcl_Obj
*CONST objv
[], int objn
));
136 static int tclsetoption
_ANSI_ARGS_ ((Tcl_Interp
*interp
, int objc
, Tcl_Obj
*CONST objv
[], int objn
));
137 static int tclvimexpr
_ANSI_ARGS_ ((Tcl_Interp
*interp
, int objc
, Tcl_Obj
*CONST objv
[], int objn
));
138 static void tcldelthisinterp
_ANSI_ARGS_ ((void));
140 static int vimerror
_ANSI_ARGS_((Tcl_Interp
*interp
));
141 static void tclmsg
_ANSI_ARGS_((char *text
));
142 static void tclerrmsg
_ANSI_ARGS_((char *text
));
143 static void tclupdatevars
_ANSI_ARGS_((void));
145 static struct ref refsdeleted
; /* dummy object for deleted ref list */
147 /*****************************************************************************
148 * TCL interface manager
149 ****************************************************************************/
151 #if defined(DYNAMIC_TCL) || defined(PROTO)
152 # ifndef DYNAMIC_TCL_DLL
153 # define DYNAMIC_TCL_DLL "tcl83.dll"
155 # ifndef DYNAMIC_TCL_VER
156 # define DYNAMIC_TCL_VER "8.3"
159 # ifndef DYNAMIC_TCL /* Just generating prototypes */
164 * Declare HANDLE for tcl.dll and function pointers.
166 static HANDLE hTclLib
= NULL
;
167 Tcl_Interp
* (*dll_Tcl_CreateInterp
)();
170 * Table of name to function pointer of tcl.
172 #define TCL_PROC FARPROC
176 } tcl_funcname_table
[] = {
177 {"Tcl_CreateInterp", (TCL_PROC
*)&dll_Tcl_CreateInterp
},
182 * Make all runtime-links of tcl.
184 * 1. Get module handle using LoadLibraryEx.
185 * 2. Get pointer to tcl function by GetProcAddress.
186 * 3. Repeat 2, until get all functions will be used.
188 * Parameter 'libname' provides name of DLL.
192 tcl_runtime_link_init(char *libname
, int verbose
)
198 if (!(hTclLib
= LoadLibraryEx(libname
, NULL
, 0)))
201 EMSG2(_(e_loadlib
), libname
);
204 for (i
= 0; tcl_funcname_table
[i
].ptr
; ++i
)
206 if (!(*tcl_funcname_table
[i
].ptr
= GetProcAddress(hTclLib
,
207 tcl_funcname_table
[i
].name
)))
209 FreeLibrary(hTclLib
);
212 EMSG2(_(e_loadfunc
), tcl_funcname_table
[i
].name
);
218 #endif /* defined(DYNAMIC_TCL) || defined(PROTO) */
221 static char *find_executable_arg
= NULL
;
229 Tcl_FindExecutable(arg
);
231 find_executable_arg
= arg
;
235 #if defined(DYNAMIC_TCL) || defined(PROTO)
237 static int stubs_initialized
= FALSE
;
240 * Return TRUE if the TCL interface can be used.
246 if (!stubs_initialized
&& find_executable_arg
!= NULL
247 && tcl_runtime_link_init(DYNAMIC_TCL_DLL
, verbose
) == OK
)
251 if (interp
= dll_Tcl_CreateInterp())
253 if (Tcl_InitStubs(interp
, DYNAMIC_TCL_VER
, 0))
255 Tcl_FindExecutable(find_executable_arg
);
256 Tcl_DeleteInterp(interp
);
257 stubs_initialized
= TRUE
;
259 /* FIXME: When Tcl_InitStubs() was failed, how delete interp? */
262 return stubs_initialized
;
272 FreeLibrary(hTclLib
);
278 /****************************************************************************
280 ****************************************************************************/
283 * Replace standard "exit" and "catch" commands.
285 * This is a design flaw in Tcl - the standard "exit" command just calls
286 * exit() and kills the application. It should return TCL_EXIT to the
287 * app, which then decides if it wants to terminate or not. In our case,
288 * we just delete the Tcl interpreter (and create a new one with the next
294 exitcmd(dummy
, interp
, objc
, objv
)
295 ClientData dummy UNUSED
;
298 Tcl_Obj
*CONST objv
[];
305 if (Tcl_GetIntFromObj(interp
, objv
[1], &value
) != TCL_OK
)
309 Tcl_SetObjResult(interp
, Tcl_NewIntObj(value
));
312 Tcl_WrongNumArgs(interp
, 1, objv
, "?returnCode?");
318 catchcmd(dummy
, interp
, objc
, objv
)
319 ClientData dummy UNUSED
;
322 Tcl_Obj
*CONST objv
[];
324 char *varname
= NULL
;
330 varname
= Tcl_GetStringFromObj(objv
[2], NULL
);
333 Tcl_ResetResult(interp
);
334 Tcl_AllowExceptions(interp
);
335 result
= Tcl_EvalObj(interp
, objv
[1]);
336 if (result
== TCL_EXIT
)
340 if (Tcl_SetVar(interp
, varname
, Tcl_GetStringResult(interp
), 0) == NULL
)
342 Tcl_SetResult(interp
, "couldn't save command result in variable", TCL_STATIC
);
346 Tcl_SetObjResult(interp
, Tcl_NewIntObj(result
));
349 Tcl_WrongNumArgs(interp
, 1, objv
, "command ?varName?");
355 * "::vim::beep" - what Vi[m] does best :-)
358 beepcmd(dummy
, interp
, objc
, objv
)
359 ClientData dummy UNUSED
;
362 Tcl_Obj
*CONST objv
[];
366 Tcl_WrongNumArgs(interp
, 1, objv
, NULL
);
374 * "::vim::buffer list" - create a list of buffer commands.
375 * "::vim::buffer {N}" - create buffer command for buffer N.
376 * "::vim::buffer new" - create a new buffer (not implemented)
379 buffercmd(dummy
, interp
, objc
, objv
)
380 ClientData dummy UNUSED
;
383 Tcl_Obj
*CONST objv
[];
389 enum {BCMD_EXISTS
, BCMD_LIST
};
390 static CONST84
char *bcmdoptions
[] =
392 "exists", "list", (char *)0
397 Tcl_WrongNumArgs(interp
, 1, objv
, "option");
400 err
= Tcl_GetIntFromObj(interp
, objv
[1], &n
);
405 Tcl_WrongNumArgs(interp
, 1, objv
, "bufNumber");
408 for (buf
= firstbuf
; buf
!= NULL
; buf
= buf
->b_next
)
410 if (buf
->b_fnum
== n
)
412 name
= tclgetbuffer(interp
, buf
);
415 Tcl_SetResult(interp
, name
, TCL_VOLATILE
);
419 Tcl_SetResult(interp
, _("invalid buffer number"), TCL_STATIC
);
422 Tcl_ResetResult(interp
); /* clear error from Tcl_GetIntFromObj */
424 err
= Tcl_GetIndexFromObj(interp
, objv
[1], bcmdoptions
, "option", 0, &idx
);
432 Tcl_WrongNumArgs(interp
, 2, objv
, "");
436 for (buf
= firstbuf
; buf
!= NULL
; buf
= buf
->b_next
)
438 name
= tclgetbuffer(interp
, buf
);
444 Tcl_AppendElement(interp
, name
);
451 Tcl_WrongNumArgs(interp
, 2, objv
, "bufNumber");
455 err
= Tcl_GetIntFromObj(interp
, objv
[2], &n
);
458 buf
= buflist_findnr(n
);
459 resobj
= Tcl_NewIntObj(buf
!= NULL
);
460 Tcl_SetObjResult(interp
, resobj
);
465 Tcl_SetResult(interp
, _("not implemented yet"), TCL_STATIC
);
472 * "::vim::window list" - create list of window commands.
475 windowcmd(dummy
, interp
, objc
, objv
)
476 ClientData dummy UNUSED
;
479 Tcl_Obj
*CONST objv
[];
486 Tcl_WrongNumArgs(interp
, 1, objv
, "option");
489 what
= Tcl_GetStringFromObj(objv
[1], NULL
);
490 if (strcmp(what
, "list") == 0)
494 string
= tclgetwindow(interp
, win
);
497 Tcl_AppendElement(interp
, string
);
501 Tcl_SetResult(interp
, _("unknown option"), TCL_STATIC
);
506 * flags for bufselfcmd and winselfcmd to indicate outstanding actions.
508 #define FL_UPDATE_SCREEN (1<<0)
509 #define FL_UPDATE_CURBUF (1<<1)
510 #define FL_ADJUST_CURSOR (1<<2)
513 * This function implements the buffer commands.
516 bufselfcmd(ref
, interp
, objc
, objv
)
520 Tcl_Obj
*CONST objv
[];
522 int opt
, err
, idx
, flags
;
523 int val1
, val2
, n
, i
;
524 buf_T
*buf
, *savebuf
;
525 win_T
*win
, *savewin
;
532 BUF_APPEND
, BUF_COMMAND
, BUF_COUNT
, BUF_DELCMD
, BUF_DELETE
, BUF_EXPR
,
533 BUF_GET
, BUF_INSERT
, BUF_LAST
, BUF_MARK
, BUF_NAME
, BUF_NUMBER
,
534 BUF_OPTION
, BUF_SET
, BUF_WINDOWS
536 static CONST84
char *bufoptions
[] =
538 "append", "command", "count", "delcmd", "delete", "expr",
539 "get", "insert", "last", "mark", "name", "number",
540 "option", "set", "windows", (char *)0
545 Tcl_WrongNumArgs(interp
, 1, objv
, "option ?arg ...?");
549 err
= Tcl_GetIndexFromObj(interp
, objv
[1], bufoptions
, "option", 0, &idx
);
553 buf
= (buf_T
*)((struct ref
*)ref
)->vimobj
;
554 savebuf
= curbuf
; curbuf
= buf
;
555 savewin
= curwin
; curwin
= tclfindwin(buf
);
562 err
= tcldoexcommand(interp
, objc
, objv
, 2);
563 flags
|= FL_UPDATE_SCREEN
;
567 err
= tclsetoption(interp
, objc
, objv
, 2);
568 flags
|= FL_UPDATE_SCREEN
;
572 err
= tclvimexpr(interp
, objc
, objv
, 2);
577 * Get filename of buffer.
581 Tcl_WrongNumArgs(interp
, 2, objv
, NULL
);
586 Tcl_SetResult(interp
, (char *)buf
->b_ffname
, TCL_VOLATILE
);
588 Tcl_SetResult(interp
, "", TCL_STATIC
);
593 * Get line number of last line.
599 * Get number of lines in buffer.
603 Tcl_WrongNumArgs(interp
, 2, objv
, NULL
);
607 val1
= (int)buf
->b_ml
.ml_line_count
;
609 val1
= row2tcl(val1
);
611 resobj
= Tcl_NewIntObj(val1
);
612 Tcl_SetObjResult(interp
, resobj
);
617 * Get buffer's number.
621 Tcl_WrongNumArgs(interp
, 2, objv
, NULL
);
625 resobj
= Tcl_NewIntObj((int)buf
->b_fnum
);
626 Tcl_SetObjResult(interp
, resobj
);
630 if (objc
!= 3 && objc
!= 4)
632 Tcl_WrongNumArgs(interp
, 2, objv
, "lineNumber ?lineNumber?");
636 err
= tclgetlinenum(interp
, objv
[2], &val1
, buf
);
641 err
= tclgetlinenum(interp
, objv
[3], &val2
, buf
);
646 n
= val1
; val1
= val2
; val2
= n
;
648 Tcl_ResetResult(interp
);
650 for (n
= val1
; n
<= val2
&& err
== TCL_OK
; n
++)
652 line
= (char *)ml_get_buf(buf
, (linenr_T
)n
, FALSE
);
654 Tcl_AppendElement(interp
, line
);
659 else { /* objc == 3 */
660 line
= (char *)ml_get_buf(buf
, (linenr_T
)val1
, FALSE
);
661 Tcl_SetResult(interp
, line
, TCL_VOLATILE
);
666 if (objc
!= 4 && objc
!= 5)
668 Tcl_WrongNumArgs(interp
, 3, objv
, "lineNumber ?lineNumber? stringOrList");
672 err
= tclgetlinenum(interp
, objv
[2], &val1
, buf
);
678 * Replace one line with a string.
679 * $buf set {n} {string}
681 line
= Tcl_GetStringFromObj(objv
[3], NULL
);
682 if (u_savesub((linenr_T
)val1
) != OK
)
684 Tcl_SetResult(interp
, _("cannot save undo information"), TCL_STATIC
);
688 if (ml_replace((linenr_T
)val1
, (char_u
*)line
, TRUE
) != OK
)
690 Tcl_SetResult(interp
, _("cannot replace line"), TCL_STATIC
);
695 changed_bytes((linenr_T
)val1
, 0);
696 flags
|= FL_UPDATE_CURBUF
;
703 * Replace several lines with the elements of a Tcl list.
704 * $buf set {n} {m} {list}
705 * If the list contains more than {m}-{n}+1 elements, they
706 * are * inserted after line {m}. If the list contains fewer
707 * elements, * the lines from {n}+length({list}) through {m}
713 err
= tclgetlinenum(interp
, objv
[3], &val2
, buf
);
716 err
= Tcl_ListObjGetElements(interp
, objv
[4], &lc
, &lv
);
727 if (u_save((linenr_T
)(val1
- 1), (linenr_T
)(val2
+ 1)) != OK
)
729 Tcl_SetResult(interp
, _("cannot save undo information"),
734 flags
|= FL_UPDATE_CURBUF
;
736 for (i
= 0; i
< lc
&& n
<= val2
; i
++)
738 line
= Tcl_GetStringFromObj(lv
[i
], NULL
);
739 if (ml_replace((linenr_T
)n
, (char_u
*)line
, TRUE
) != OK
)
748 line
= Tcl_GetStringFromObj(lv
[i
], NULL
);
749 if (ml_append((linenr_T
)(n
- 1),
750 (char_u
*)line
, 0, FALSE
) != OK
)
758 /* did not replace all lines, delete */
762 if (ml_delete((linenr_T
)i
, FALSE
) != OK
)
767 lc
-= val2
- val1
+ 1; /* number of lines to be replaced */
768 mark_adjust((linenr_T
)val1
, (linenr_T
)val2
, (long)MAXLNUM
,
770 changed_lines((linenr_T
)val1
, 0, (linenr_T
)val2
+ 1, (long)lc
);
774 Tcl_SetResult(interp
, _("cannot set line(s)"), TCL_STATIC
);
780 if (objc
!= 3 && objc
!= 4)
782 Tcl_WrongNumArgs(interp
, 3, objv
, "lineNumber ?lineNumber?");
786 err
= tclgetlinenum(interp
, objv
[2], &val1
, buf
);
792 err
= tclgetlinenum(interp
, objv
[3], &val2
, buf
);
797 i
= val1
; val1
= val2
; val2
= i
;
801 if (u_savedel((linenr_T
)val1
, (long)n
) != OK
)
803 Tcl_SetResult(interp
, _("cannot save undo information"),
808 for (i
= 0; i
< n
; i
++)
810 ml_delete((linenr_T
)val1
, FALSE
);
811 err
= vimerror(interp
);
816 deleted_lines_mark((linenr_T
)val1
, (long)i
);
817 flags
|= FL_ADJUST_CURSOR
|FL_UPDATE_SCREEN
;
823 Tcl_WrongNumArgs(interp
, 2, objv
, "markName");
827 line
= Tcl_GetStringFromObj(objv
[2], NULL
);
830 if (line
[0] != '\0' && line
[1] == '\0')
832 pos
= getmark(line
[0], FALSE
);
836 Tcl_SetResult(interp
, _("invalid mark name"), TCL_STATIC
);
840 err
= vimerror(interp
);
845 Tcl_SetResult(interp
, _("mark not set"), TCL_STATIC
);
852 sprintf(rbuf
, _("row %d column %d"),
853 (int)row2tcl(pos
->lnum
), (int)col2tcl(pos
->col
));
854 Tcl_SetResult(interp
, rbuf
, TCL_VOLATILE
);
864 Tcl_WrongNumArgs(interp
, 2, objv
, "lineNum text");
868 err
= tclgetlinenum(interp
, objv
[2], &val1
, buf
);
873 if (u_save((linenr_T
)val1
, (linenr_T
)(val1
+1)) != OK
)
875 Tcl_SetResult(interp
, _("cannot save undo information"),
881 line
= Tcl_GetStringFromObj(objv
[3], NULL
);
882 if (ml_append((linenr_T
)val1
, (char_u
*)line
, 0, FALSE
) != OK
)
884 Tcl_SetResult(interp
, _("cannot insert/append line"),
889 appended_lines_mark((linenr_T
)val1
, 1L);
890 flags
|= FL_UPDATE_SCREEN
;
895 * Return list of window commands.
899 Tcl_WrongNumArgs(interp
, 2, objv
, NULL
);
903 Tcl_ResetResult(interp
);
906 if (win
->w_buffer
== buf
)
908 line
= tclgetwindow(interp
, win
);
910 Tcl_AppendElement(interp
, line
);
922 * Register deletion callback.
923 * TODO: Should be able to register multiple callbacks
927 Tcl_WrongNumArgs(interp
, 2, objv
, "command");
931 err
= tclsetdelcmd(interp
, buf
->b_tcl_ref
, (void *)buf
, objv
[2]);
935 Tcl_SetResult(interp
, _("not implemented yet"), TCL_STATIC
);
939 if (flags
& FL_UPDATE_CURBUF
)
940 redraw_curbuf_later(NOT_VALID
);
943 if (flags
& FL_ADJUST_CURSOR
)
945 if (flags
& (FL_UPDATE_SCREEN
| FL_UPDATE_CURBUF
))
946 update_screen(NOT_VALID
);
952 * This function implements the window commands.
955 winselfcmd(ref
, interp
, objc
, objv
)
959 Tcl_Obj
*CONST objv
[];
964 win_T
*savewin
, *win
;
970 WIN_BUFFER
, WIN_COMMAND
, WIN_CURSOR
, WIN_DELCMD
, WIN_EXPR
,
971 WIN_HEIGHT
, WIN_OPTION
973 static CONST84
char *winoptions
[] =
975 "buffer", "command", "cursor", "delcmd", "expr",
976 "height", "option", (char *)0
981 Tcl_WrongNumArgs(interp
, 1, objv
, "option ?arg ...?");
985 err
= Tcl_GetIndexFromObj(interp
, objv
[1], winoptions
, "option", 0, &idx
);
989 win
= (win_T
*)((struct ref
*)ref
)->vimobj
;
990 savewin
= curwin
; curwin
= win
;
991 savebuf
= curbuf
; curbuf
= win
->w_buffer
;
997 err
= tclsetoption(interp
, objc
, objv
, 2);
998 flags
|= FL_UPDATE_SCREEN
;
1002 err
= tcldoexcommand(interp
, objc
, objv
, 2);
1003 flags
|= FL_UPDATE_SCREEN
;
1007 err
= tclvimexpr(interp
, objc
, objv
, 2);
1013 err
= Tcl_GetIntFromObj(interp
, objv
[2], &val1
);
1017 need_mouse_correct
= TRUE
;
1019 win_setheight(val1
);
1020 err
= vimerror(interp
);
1027 Tcl_WrongNumArgs(interp
, 2, objv
, "?value?");
1032 resobj
= Tcl_NewIntObj((int)(win
->w_height
));
1033 Tcl_SetObjResult(interp
, resobj
);
1039 Tcl_WrongNumArgs(interp
, 2, objv
, NULL
);
1043 str
= tclgetbuffer(interp
, win
->w_buffer
);
1045 Tcl_SetResult(interp
, str
, TCL_VOLATILE
);
1053 Tcl_WrongNumArgs(interp
, 2, objv
, "command");
1057 err
= tclsetdelcmd(interp
, win
->w_tcl_ref
, (void *)win
, objv
[2]);
1063 Tcl_WrongNumArgs(interp
, 2, objv
, "?arg1 ?arg2??");
1071 sprintf(buf
, _("row %d column %d"), (int)row2tcl(win
->w_cursor
.lnum
), (int)col2tcl(win
->w_cursor
.col
));
1072 Tcl_SetResult(interp
, buf
, TCL_VOLATILE
);
1077 Tcl_Obj
*part
, *var
;
1079 part
= Tcl_NewStringObj("row", -1);
1080 var
= Tcl_ObjGetVar2(interp
, objv
[2], part
, TCL_LEAVE_ERR_MSG
);
1086 err
= tclgetlinenum(interp
, var
, &val1
, win
->w_buffer
);
1089 part
= Tcl_NewStringObj("column", -1);
1090 var
= Tcl_ObjGetVar2(interp
, objv
[2], part
, TCL_LEAVE_ERR_MSG
);
1096 err
= Tcl_GetIntFromObj(interp
, var
, &val2
);
1100 else { /* objc == 4 */
1101 err
= tclgetlinenum(interp
, objv
[2], &val1
, win
->w_buffer
);
1104 err
= Tcl_GetIntFromObj(interp
, objv
[3], &val2
);
1108 /* TODO: should check column */
1109 win
->w_cursor
.lnum
= val1
;
1110 win
->w_cursor
.col
= col2vim(val2
);
1111 flags
|= FL_UPDATE_SCREEN
;
1115 Tcl_SetResult(interp
, _("not implemented yet"), TCL_STATIC
);
1121 if (flags
& FL_UPDATE_SCREEN
)
1122 update_screen(NOT_VALID
);
1129 commandcmd(dummy
, interp
, objc
, objv
)
1130 ClientData dummy UNUSED
;
1133 Tcl_Obj
*CONST objv
[];
1137 err
= tcldoexcommand(interp
, objc
, objv
, 1);
1138 update_screen(VALID
);
1143 optioncmd(dummy
, interp
, objc
, objv
)
1144 ClientData dummy UNUSED
;
1147 Tcl_Obj
*CONST objv
[];
1151 err
= tclsetoption(interp
, objc
, objv
, 1);
1152 update_screen(VALID
);
1157 exprcmd(dummy
, interp
, objc
, objv
)
1158 ClientData dummy UNUSED
;
1161 Tcl_Obj
*CONST objv
[];
1163 return tclvimexpr(interp
, objc
, objv
, 1);
1166 /****************************************************************************
1167 Support functions for Tcl commands
1168 ****************************************************************************/
1171 * Get a line number from 'obj' and convert it to vim's range.
1174 tclgetlinenum(interp
, obj
, valueP
, buf
)
1182 enum { LN_BEGIN
, LN_BOTTOM
, LN_END
, LN_FIRST
, LN_LAST
, LN_START
, LN_TOP
};
1184 static CONST84
char *keyw
[] =
1186 "begin", "bottom", "end", "first", "last", "start", "top", (char *)0
1189 err
= Tcl_GetIndexFromObj(interp
, obj
, keyw
, "", 0, &i
);
1203 *valueP
= buf
->b_ml
.ml_line_count
;
1208 Tcl_ResetResult(interp
);
1210 err
= Tcl_GetIntFromObj(interp
, obj
, &i
);
1214 if (i
< 1 || i
> buf
->b_ml
.ml_line_count
)
1216 Tcl_SetResult(interp
, _("line number out of range"), TCL_STATIC
);
1224 * Find the first window in the window list that displays the buffer.
1232 FOR_ALL_WINDOWS(win
)
1234 if (win
->w_buffer
== buf
)
1237 return curwin
; /* keep current window context */
1241 * Do-it-all function for "::vim::command", "$buf command" and "$win command".
1244 tcldoexcommand(interp
, objc
, objv
, objn
)
1247 Tcl_Obj
*CONST objv
[];
1251 int err
, flag
, nobjs
;
1254 nobjs
= objc
- objn
;
1255 if (nobjs
< 1 || nobjs
> 2)
1257 Tcl_WrongNumArgs(interp
, objn
, objv
, "?-quiet? exCommand");
1264 arg
= Tcl_GetStringFromObj(objv
[objn
], NULL
);
1265 if (strcmp(arg
, "-quiet") == 0)
1269 Tcl_ResetResult(interp
);
1270 Tcl_AppendResult(interp
, _("unknown flag: "), arg
, (char *)0);
1276 memcpy(&saveinfo
, &tclinfo
, sizeof(tcl_info
));
1277 tclinfo
.interp
= NULL
;
1278 tclinfo
.curwin
= NULL
;
1279 tclinfo
.curbuf
= NULL
;
1281 arg
= Tcl_GetStringFromObj(objv
[objn
], NULL
);
1284 do_cmdline_cmd((char_u
*)arg
);
1287 err
= vimerror(interp
);
1289 /* If the ex command created a new Tcl interpreter, remove it */
1292 memcpy(&tclinfo
, &saveinfo
, sizeof(tcl_info
));
1299 * Do-it-all function for "::vim::option", "$buf option" and "$win option".
1302 tclsetoption(interp
, objc
, objv
, objn
)
1305 Tcl_Obj
*CONST objv
[];
1308 int err
, nobjs
, idx
;
1315 enum { OPT_OFF
, OPT_ON
, OPT_TOGGLE
};
1316 static CONST84
char *optkw
[] = { "off", "on", "toggle", (char *)0 };
1318 nobjs
= objc
- objn
;
1319 if (nobjs
!= 1 && nobjs
!= 2)
1321 Tcl_WrongNumArgs(interp
, objn
, objv
, "vimOption ?value?");
1325 option
= (char_u
*)Tcl_GetStringFromObj(objv
[objn
], NULL
);
1327 isnum
= get_option_value(option
, &lval
, &sval
, 0);
1332 Tcl_SetResult(interp
, (char *)sval
, TCL_VOLATILE
);
1336 resobj
= Tcl_NewLongObj(lval
);
1337 Tcl_SetObjResult(interp
, resobj
);
1340 Tcl_SetResult(interp
, _("unknown vimOption"), TCL_STATIC
);
1347 sval
= NULL
; /* avoid compiler warning */
1348 err
= Tcl_GetIndexFromObj(interp
, objv
[objn
], optkw
, "", 0, &idx
);
1351 Tcl_ResetResult(interp
);
1352 err
= Tcl_GetLongFromObj(interp
, objv
[objn
], &lval
);
1369 sval
= (char_u
*)Tcl_GetStringFromObj(objv
[objn
], NULL
);
1372 set_option_value(option
, lval
, sval
, OPT_LOCAL
);
1373 err
= vimerror(interp
);
1380 * Do-it-all function for "::vim::expr", "$buf expr" and "$win expr".
1383 tclvimexpr(interp
, objc
, objv
, objn
)
1386 Tcl_Obj
*CONST objv
[];
1394 if (objc
- objn
!= 1)
1396 Tcl_WrongNumArgs(interp
, objn
, objv
, "vimExpr");
1401 expr
= Tcl_GetStringFromObj(objv
[objn
], NULL
);
1402 str
= (char *)eval_to_string((char_u
*)expr
, NULL
, TRUE
);
1404 Tcl_SetResult(interp
, _("invalid expression"), TCL_STATIC
);
1406 Tcl_SetResult(interp
, str
, TCL_VOLATILE
);
1407 err
= vimerror(interp
);
1409 Tcl_SetResult(interp
, _("expressions disabled at compile time"), TCL_STATIC
);
1417 * Check for internal vim errors.
1425 Tcl_SetResult(interp
, _("keyboard interrupt"), TCL_STATIC
);
1430 Tcl_SetResult(interp
, _("vim error"), TCL_STATIC
);
1437 * Functions that handle the reference lists:
1438 * delref() - callback for Tcl's DeleteCommand
1439 * tclgetref() - find/create Tcl command for a win_T* or buf_T* object
1440 * tclgetwindow() - window frontend for tclgetref()
1441 * tclgetbuffer() - buffer frontend for tclgetref()
1442 * tclsetdelcmd() - add Tcl callback command to a vim object
1448 struct ref
*ref
= (struct ref
*)cref
;
1452 Tcl_DecrRefCount(ref
->delcmd
);
1459 tclgetref(interp
, refstartP
, prefix
, vimobj
, proc
)
1461 void **refstartP
; /* ptr to w_tcl_ref/b_tcl-ref member of
1462 win_T/buf_T struct */
1463 char *prefix
; /* "win" or "buf" */
1464 void *vimobj
; /* win_T* or buf_T* */
1465 Tcl_ObjCmdProc
*proc
; /* winselfcmd or bufselfcmd */
1467 struct ref
*ref
, *unused
= NULL
;
1468 static char name
[VARNAME_SIZE
];
1471 ref
= (struct ref
*)(*refstartP
);
1472 if (ref
== &refsdeleted
)
1474 Tcl_SetResult(interp
, _("cannot create buffer/window command: object is being deleted"), TCL_STATIC
);
1480 if (ref
->interp
== interp
)
1482 if (ref
->interp
== NULL
)
1488 vim_snprintf(name
, sizeof(name
), "::vim::%s",
1489 Tcl_GetCommandName(interp
, ref
->cmd
));
1496 ref
= (struct ref
*)Tcl_Alloc(sizeof(struct ref
));
1497 #if 0 /* Tcl_Alloc either succeeds or does not return */
1500 Tcl_SetResult(interp
, "out of memory", TCL_STATIC
);
1505 ref
->next
= (struct ref
*)(*refstartP
);
1506 (*refstartP
) = (void *)ref
;
1509 /* This might break on some exotic systems... */
1510 vim_snprintf(name
, sizeof(name
), "::vim::%s_%lx",
1511 prefix
, (unsigned long)vimobj
);
1512 cmd
= Tcl_CreateObjCommand(interp
, name
, proc
,
1513 (ClientData
)ref
, (Tcl_CmdDeleteProc
*)delref
);
1517 ref
->interp
= interp
;
1520 ref
->vimobj
= vimobj
;
1526 tclgetwindow(interp
, win
)
1530 return tclgetref(interp
, &(win
->w_tcl_ref
), "win", (void *)win
, winselfcmd
);
1534 tclgetbuffer(interp
, buf
)
1538 return tclgetref(interp
, &(buf
->b_tcl_ref
), "buf", (void *)buf
, bufselfcmd
);
1542 tclsetdelcmd(interp
, reflist
, vimobj
, delcmd
)
1544 struct ref
*reflist
;
1548 if (reflist
== &refsdeleted
)
1550 Tcl_SetResult(interp
, _("cannot register callback command: buffer/window is already being deleted"), TCL_STATIC
);
1554 while (reflist
!= NULL
)
1556 if (reflist
->interp
== interp
&& reflist
->vimobj
== vimobj
)
1558 if (reflist
->delcmd
)
1560 Tcl_DecrRefCount(reflist
->delcmd
);
1562 Tcl_IncrRefCount(delcmd
);
1563 reflist
->delcmd
= delcmd
;
1566 reflist
= reflist
->next
;
1568 /* This should never happen. Famous last word? */
1569 EMSG(_("E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim.org"));
1570 Tcl_SetResult(interp
, _("cannot register callback command: buffer/window reference not found"), TCL_STATIC
);
1575 /*******************************************
1577 ********************************************/
1580 channel_close(instance
, interp
)
1581 ClientData instance
;
1582 Tcl_Interp
*interp UNUSED
;
1586 /* currently does nothing */
1588 if (instance
!= VIMOUT
&& instance
!= VIMERR
)
1590 Tcl_SetErrno(EBADF
);
1597 channel_input(instance
, buf
, bufsiz
, errptr
)
1598 ClientData instance UNUSED
;
1604 /* input is currently not supported */
1606 Tcl_SetErrno(EINVAL
);
1613 channel_output(instance
, buf
, bufsiz
, errptr
)
1614 ClientData instance
;
1622 /* The buffer is not guaranteed to be 0-terminated, and we don't if
1623 * there is enough room to add a '\0'. So we have to create a copy
1626 str
= vim_strnsave((char_u
*)buf
, bufsiz
);
1629 Tcl_SetErrno(ENOMEM
);
1636 if (instance
== VIMOUT
)
1637 tclmsg((char *)str
);
1639 if (instance
== VIMERR
)
1640 tclerrmsg((char *)str
);
1643 Tcl_SetErrno(EBADF
);
1653 channel_watch(instance
, mask
)
1654 ClientData instance UNUSED
;
1657 Tcl_SetErrno(EINVAL
);
1661 channel_gethandle(instance
, direction
, handleptr
)
1662 ClientData instance UNUSED
;
1663 int direction UNUSED
;
1664 ClientData
*handleptr UNUSED
;
1666 Tcl_SetErrno(EINVAL
);
1671 static Tcl_ChannelType channel_type
=
1673 "vimmessage", /* typeName */
1675 channel_close
, /* closeProc */
1676 channel_input
, /* inputProc */
1677 channel_output
, /* outputProc */
1678 NULL
, /* seekProc */
1679 NULL
, /* setOptionProc */
1680 NULL
, /* getOptionProc */
1681 channel_watch
, /* watchProc */
1682 channel_gethandle
, /* getHandleProc */
1683 NULL
, /* close2Proc */
1684 NULL
, /* blockModeProc */
1685 #ifdef TCL_CHANNEL_VERSION_2
1686 NULL
, /* flushProc */
1687 NULL
, /* handlerProc */
1689 #ifdef TCL_CHANNEL_VERSION_3
1690 NULL
, /* wideSeekProc */
1692 #ifdef TCL_CHANNEL_VERSION_4
1693 NULL
, /* threadActionProc */
1695 #ifdef TCL_CHANNEL_VERSION_5
1696 NULL
/* truncateProc */
1700 /**********************************
1702 **********************************/
1707 char varname
[VARNAME_SIZE
]; /* must be writeable */
1710 strcpy(varname
, VAR_RANGE1
);
1711 Tcl_UpdateLinkedVar(tclinfo
.interp
, varname
);
1712 strcpy(varname
, VAR_RANGE2
);
1713 Tcl_UpdateLinkedVar(tclinfo
.interp
, varname
);
1714 strcpy(varname
, VAR_RANGE3
);
1715 Tcl_UpdateLinkedVar(tclinfo
.interp
, varname
);
1717 strcpy(varname
, VAR_LBASE
);
1718 Tcl_UpdateLinkedVar(tclinfo
.interp
, varname
);
1720 name
= tclgetbuffer(tclinfo
.interp
, curbuf
);
1721 strcpy(tclinfo
.curbuf
, name
);
1722 strcpy(varname
, VAR_CURBUF
);
1723 Tcl_UpdateLinkedVar(tclinfo
.interp
, varname
);
1725 name
= tclgetwindow(tclinfo
.interp
, curwin
);
1726 strcpy(tclinfo
.curwin
, name
);
1727 strcpy(varname
, VAR_CURWIN
);
1728 Tcl_UpdateLinkedVar(tclinfo
.interp
, varname
);
1736 char varname
[VARNAME_SIZE
]; /* Tcl_LinkVar requires writeable varname */
1740 if (!tcl_enabled(TRUE
))
1742 EMSG(_("E571: Sorry, this command is disabled: the Tcl library could not be loaded."));
1747 if (!tclinfo
.interp
)
1750 static Tcl_Channel ch1
, ch2
;
1752 /* replace stdout and stderr */
1753 ch1
= Tcl_CreateChannel(&channel_type
, "vimout", VIMOUT
, TCL_WRITABLE
);
1754 ch2
= Tcl_CreateChannel(&channel_type
, "vimerr", VIMERR
, TCL_WRITABLE
);
1755 Tcl_SetStdChannel(ch1
, TCL_STDOUT
);
1756 Tcl_SetStdChannel(ch2
, TCL_STDERR
);
1758 interp
= Tcl_CreateInterp();
1759 Tcl_Preserve(interp
);
1760 if (Tcl_Init(interp
) == TCL_ERROR
)
1762 Tcl_Release(interp
);
1763 Tcl_DeleteInterp(interp
);
1767 /* VIM sure is interactive */
1768 Tcl_SetVar(interp
, "tcl_interactive", "1", TCL_GLOBAL_ONLY
);
1771 Tcl_SetChannelOption(interp
, ch1
, "-buffering", "line");
1772 Tcl_SetChannelOption(interp
, ch2
, "-buffering", "line");
1774 /* replace some standard Tcl commands */
1775 Tcl_DeleteCommand(interp
, "exit");
1776 Tcl_CreateObjCommand(interp
, "exit", exitcmd
,
1777 (ClientData
)NULL
, (Tcl_CmdDeleteProc
*)NULL
);
1778 Tcl_DeleteCommand(interp
, "catch");
1779 Tcl_CreateObjCommand(interp
, "catch", catchcmd
,
1780 (ClientData
)NULL
, (Tcl_CmdDeleteProc
*)NULL
);
1782 /* new commands, in ::vim namespace */
1783 Tcl_CreateObjCommand(interp
, "::vim::buffer", buffercmd
,
1784 (ClientData
)NULL
, (Tcl_CmdDeleteProc
*)NULL
);
1785 Tcl_CreateObjCommand(interp
, "::vim::window", windowcmd
,
1786 (ClientData
)NULL
, (Tcl_CmdDeleteProc
*)NULL
);
1787 Tcl_CreateObjCommand(interp
, "::vim::command", commandcmd
,
1788 (ClientData
)NULL
, (Tcl_CmdDeleteProc
*)NULL
);
1789 Tcl_CreateObjCommand(interp
, "::vim::beep", beepcmd
,
1790 (ClientData
)NULL
, (Tcl_CmdDeleteProc
*)NULL
);
1791 Tcl_CreateObjCommand(interp
, "::vim::option", optioncmd
,
1792 (ClientData
)NULL
, (Tcl_CmdDeleteProc
*)NULL
);
1793 Tcl_CreateObjCommand(interp
, "::vim::expr", exprcmd
,
1794 (ClientData
)NULL
, (Tcl_CmdDeleteProc
*)NULL
);
1796 /* "lbase" variable */
1798 strcpy(varname
, VAR_LBASE
);
1799 Tcl_LinkVar(interp
, varname
, (char *)&tclinfo
.lbase
, TCL_LINK_INT
);
1801 /* "range" variable */
1802 tclinfo
.range_start
= eap
->line1
;
1803 strcpy(varname
, VAR_RANGE1
);
1804 Tcl_LinkVar(interp
, varname
, (char *)&tclinfo
.range_start
, TCL_LINK_INT
|TCL_LINK_READ_ONLY
);
1805 strcpy(varname
, VAR_RANGE2
);
1806 Tcl_LinkVar(interp
, varname
, (char *)&tclinfo
.range_start
, TCL_LINK_INT
|TCL_LINK_READ_ONLY
);
1807 tclinfo
.range_end
= eap
->line2
;
1808 strcpy(varname
, VAR_RANGE3
);
1809 Tcl_LinkVar(interp
, varname
, (char *)&tclinfo
.range_end
, TCL_LINK_INT
|TCL_LINK_READ_ONLY
);
1811 /* "current" variable */
1812 tclinfo
.curbuf
= Tcl_Alloc(VARNAME_SIZE
);
1813 tclinfo
.curwin
= Tcl_Alloc(VARNAME_SIZE
);
1814 name
= tclgetbuffer(interp
, curbuf
);
1815 strcpy(tclinfo
.curbuf
, name
);
1816 strcpy(varname
, VAR_CURBUF
);
1817 Tcl_LinkVar(interp
, varname
, (char *)&tclinfo
.curbuf
, TCL_LINK_STRING
|TCL_LINK_READ_ONLY
);
1818 name
= tclgetwindow(interp
, curwin
);
1819 strcpy(tclinfo
.curwin
, name
);
1820 strcpy(varname
, VAR_CURWIN
);
1821 Tcl_LinkVar(interp
, varname
, (char *)&tclinfo
.curwin
, TCL_LINK_STRING
|TCL_LINK_READ_ONLY
);
1823 tclinfo
.interp
= interp
;
1827 /* Interpreter already exists, just update variables */
1828 tclinfo
.range_start
= row2tcl(eap
->line1
);
1829 tclinfo
.range_end
= row2tcl(eap
->line2
);
1841 while ((next
=strchr(text
, '\n')))
1857 while ((next
=strchr(text
, '\n')))
1870 if (!Tcl_InterpDeleted(tclinfo
.interp
))
1871 Tcl_DeleteInterp(tclinfo
.interp
);
1872 Tcl_Release(tclinfo
.interp
);
1873 /* The interpreter is now gets deleted. All registered commands (esp.
1874 * window and buffer commands) are deleted, triggering their deletion
1875 * callback, which deletes all refs pointing to this interpreter.
1876 * We could garbage-collect the unused ref structs in all windows and
1877 * buffers, but unless the user creates hundreds of sub-interpreters
1878 * all referring to lots of windows and buffers, this is hardly worth
1879 * the effort. Unused refs are recycled by other interpreters, and
1880 * all refs are free'd when the window/buffer gets closed by vim.
1883 tclinfo
.interp
= NULL
;
1884 Tcl_Free(tclinfo
.curbuf
);
1885 Tcl_Free(tclinfo
.curwin
);
1886 tclinfo
.curbuf
= tclinfo
.curwin
= NULL
;
1895 if (error
== TCL_EXIT
)
1901 robj
= Tcl_GetObjResult(tclinfo
.interp
);
1902 if( Tcl_GetIntFromObj(tclinfo
.interp
, robj
, &retval
) != TCL_OK
)
1904 EMSG(_("E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"));
1909 sprintf(buf
, _("E572: exit code %d"), retval
);
1926 result
= (char *)Tcl_GetStringResult(tclinfo
.interp
);
1927 if (error
== TCL_OK
)
1952 script
= script_get(eap
, eap
->arg
);
1958 Tcl_AllowExceptions(tclinfo
.interp
);
1960 err
= Tcl_Eval(tclinfo
.interp
, (char *)eap
->arg
);
1962 err
= Tcl_Eval(tclinfo
.interp
, (char *)script
);
1976 char *file
= (char *)eap
->arg
;
1982 Tcl_AllowExceptions(tclinfo
.interp
);
1983 err
= Tcl_EvalFile(tclinfo
.interp
, file
);
1995 char *script
, *line
;
1996 int err
, rs
, re
, lnum
;
1997 char var_lnum
[VARNAME_SIZE
]; /* must be writeable memory */
1998 char var_line
[VARNAME_SIZE
];
1999 linenr_T first_line
= 0;
2000 linenr_T last_line
= 0;
2004 script
= (char *)eap
->arg
;
2005 strcpy(var_lnum
, VAR_CURLNUM
);
2006 strcpy(var_line
, VAR_CURLINE
);
2013 Tcl_LinkVar(tclinfo
.interp
, var_lnum
, (char *)&lnum
, TCL_LINK_INT
|TCL_LINK_READ_ONLY
);
2015 if (u_save((linenr_T
)(rs
-1), (linenr_T
)(re
+1)) != OK
)
2017 Tcl_SetResult(tclinfo
.interp
, _("cannot save undo information"), TCL_STATIC
);
2020 while (err
== TCL_OK
&& rs
<= re
)
2022 line
= (char *)ml_get_buf(curbuf
, (linenr_T
)rs
, FALSE
);
2025 Tcl_SetResult(tclinfo
.interp
, _("cannot get line"), TCL_STATIC
);
2029 Tcl_SetVar(tclinfo
.interp
, var_line
, line
, 0);
2030 Tcl_AllowExceptions(tclinfo
.interp
);
2031 err
= Tcl_Eval(tclinfo
.interp
, script
);
2034 line
= (char *)Tcl_GetVar(tclinfo
.interp
, var_line
, 0);
2037 if (ml_replace((linenr_T
)rs
, (char_u
*)line
, TRUE
) != OK
)
2039 Tcl_SetResult(tclinfo
.interp
, _("cannot replace line"), TCL_STATIC
);
2043 if (first_line
== 0)
2049 Tcl_UpdateLinkedVar(tclinfo
.interp
, var_lnum
);
2052 changed_lines(first_line
, 0, last_line
+ 1, (long)0);
2054 Tcl_UnsetVar(tclinfo
.interp
, var_line
, 0);
2055 Tcl_UnlinkVar(tclinfo
.interp
, var_lnum
);
2057 Tcl_ResetResult(tclinfo
.interp
);
2077 err
= Tcl_GlobalEvalObj(ref
->interp
, ref
->delcmd
);
2080 result
= (char *)Tcl_GetStringResult(ref
->interp
);
2084 Tcl_DecrRefCount(ref
->delcmd
);
2087 Tcl_DeleteCommandFromToken(ref
->interp
, ref
->cmd
);
2089 Tcl_Free((char *)ref
);
2095 tcl_buffer_free(buf
)
2098 struct ref
*reflist
;
2101 if (!stubs_initialized
) /* Not using Tcl, nothing to do. */
2105 reflist
= (struct ref
*)(buf
->b_tcl_ref
);
2106 if (reflist
!= &refsdeleted
)
2108 buf
->b_tcl_ref
= (void *)&refsdeleted
;
2109 tcldelallrefs(reflist
);
2110 buf
->b_tcl_ref
= NULL
;
2114 #if defined(FEAT_WINDOWS) || defined(PROTO)
2116 tcl_window_free(win
)
2119 struct ref
*reflist
;
2122 if (!stubs_initialized
) /* Not using Tcl, nothing to do. */
2126 reflist
= (struct ref
*)(win
->w_tcl_ref
);
2127 if (reflist
!= &refsdeleted
)
2129 win
->w_tcl_ref
= (void *)&refsdeleted
;
2130 tcldelallrefs(reflist
);
2131 win
->w_tcl_ref
= NULL
;