To: vim-dev@vim.org Subject: Patch 6.1.366 (big) Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.1.366 Problem: Can't use Vim with Netbeans. Solution: Add the Netbeans interface. Includes support for sign icons and "-fg" and "-bg" arguments for GTK. Add the 'autochdir' option. (Gordon Prieur, George Hernandez, Dave Weatherford) Make it possible to display both a sign with a text and one with line highlighting in the same line. Add support for Agide, interface version 2.1. Files: runtime/doc/Makefile, runtime/doc/netbeans.txt, runtime/doc/options.txt, runtime/doc/various.txt, src/Makefile, src/auto/configure, src/buffer.c, src/config.h.in, src/config.mk.in, src/configure.in, src/edit.c, src/ex_cmds.c, src/ex_docmd.c, src/feature.h, src/fileio.c, src/globals.h, src/gui.c, src/gui_beval.c, src/gui_gtk_x11.c, src/gui_x11.c, src/main.c, src/memline.c, src/misc1.c, src/misc2.c, src/move.c, src/nbdebug.c, src/nbdebug.h, src/netbeans.c, src/normal.c, src/ops.c, src/option.c, src/option.h, src/proto/buffer.pro, src/proto/gui_beval.pro, src/proto/gui_gtk_x11.pro, src/proto/gui_x11.pro, src/proto/misc2.pro, src/proto/netbeans.pro, src/proto/normal.pro, src/proto/ui.pro, src/proto.h, src/screen.c, src/structs.h, src/ui.c, src/undo.c, src/vim.h, src/window.c, src/workshop.c *** ../vim61.365/runtime/doc/Makefile Fri Sep 14 21:08:15 2001 --- runtime/doc/Makefile Thu Feb 13 16:00:14 2003 *************** *** 46,51 **** --- 46,52 ---- motion.txt \ mbyte.txt \ mlang.txt \ + netbeans.txt \ options.txt \ os_390.txt \ os_amiga.txt \ *** ../vim61.365/runtime/doc/netbeans.txt Sat Mar 8 17:24:27 2003 --- runtime/doc/netbeans.txt Thu Mar 6 10:53:11 2003 *************** *** 0 **** --- 1,605 ---- + *netbeans.txt* For Vim version 6.1. Last change: 2003 Mar 06 + + + VIM REFERENCE MANUAL by Gordon Prieur + + + NetBeans ExternalEditor Integration Features *netbeans* + *netbeans-support* + 1. Introduction |netbeans-intro| + 2. NetBeans Key Bindings |netbeans-keybindings| + 3. Configuring Vim for NetBeans |netbeans-configure| + 4. Downloading NetBeans |netbeans-download| + 5. Preparing NetBeans for Vim |netbeans-preparation| + 6. Obtaining the External Editor Module |obtaining-exted| + 7. Setting up NetBeans to run with Vim |netbeans-setup| + 8. Messages |netbeans-messages| + 9. Running Vim from Netbeans |netbeans-run| + 10. Netbeans protocol |netbeans-protocol| + 11. Known problems |netbeans-problems| + + {Vi does not have any of these features} + {only available when compiled with the |+netbeans_intg| feature} + + ============================================================================== + 1. Introduction *netbeans-intro* + + NetBeans is an open source Integrated Development Environment developed + jointly by Sun Microsystems, Inc. and the netbeans.org developer community. + Initialy just a Java IDE, NetBeans has had C, C++, and Fortran support added + in recent releases. + + For more information visit the main NetBeans web site http://www.netbeans.org + or the NetBeans External Editor site at http://externaleditor.netbeans.org. + + Sun Microsystems, Inc. also ships NetBeans under the name Sun ONE Studio. + Visit http://www.sun.com for more information regarding the Sun ONE Studio + product line. + + Current releases of NetBeans provide full support for Java and limited support + for C, C++, and Fortran. Current releases of Sun ONE Studio provide full + support for Java, C, C++, and Fortran. + + The interface to NetBeans is also supported by Agide, the A-A-P GUI IDE. + Agide is very different from NetBeans: + - Based on Python instead of Java, much smaller footprint and fast startup. + - Agide is a framework in which many different tools can work together. + See the A-A-P website for information: http://www.A-A-P.org. + + ============================================================================== + 2. NetBeans Key Bindings *netbeans-keybindings* + + Vim understands a number of key bindings that execute NetBeans commands. These + are typically all the Function key combinations. To execute a NetBeans command, + the user must press the Pause key followed by a NetBeans key binding. For + example, in order to compile a Java file, the NetBeans key binding is "F9". So, + while in vim, press "Pause F9" to compile a java file. To toggle a breakpoint + at the current line, press "Pause Shift F8". + + The Pause key is Function key 21. If you don't have a working Pause key and + want to use F8 instead, use: > + + :map + + The External Editor module dynamically reads the NetBeans key bindings so vim + should always have the latest key bindings, even when NetBeans changes them. + + ============================================================================== + 3. Configuring Vim for NetBeans *netbeans-configure* + + The following configuration line can be used to configure vim to build for use + with NetBeans' externaleditor module: + + $ configure --enable-netbeans + + This will configure vim to build with FEAT_NETBEANS_INTG enabled. Currently, + only gvim is supported in this integration as NetBeans does not have means + to supply a terminal emulator for the vim command. Furthermore, there is only + GUI support for GTK, GNOME, and Motif. + + If Motif support is required the user must supply XPM libraries. See + |workshop-xpm| for details on obtaining the latest version of XPM. + + For more help installing vim, please read |usr_90.txt| in the Vim User Manual. + + ============================================================================== + 4. Downloading NetBeans *netbeans-download* + + The NetBeans IDE is available for download from netbeans.org. You can download + a released version, download sources, or use CVS to download the current + source tree. If you choose to download sources, follow directions from + netbeans.org on building NetBeans. + + Depending on the version of NetBeans you download, you may need to do further + work to get the required External Editor module. This is the module which lets + NetBeans work with gvim (or xemacs :-). See http://externaleditor.netbeans.org + for details on downloading this module if your NetBeans release does not have + it. + + For C, C++, and Fortran support you will also need the cpp module. See + http://cpp.netbeans.org for information regarding this module. + + You can also download Sun ONE Studio from Sun Microsystems, Inc for a 30 day + free trial. See http://www.sun.com for further details. + + ============================================================================== + 5. Preparing NetBeans for Vim *netbeans-preparation* + + In order for NetBeans to work with vim, the NetBeans External Editor module + must be loaded and enabled. If you have a Sun ONE Studio Enterprise Edition + then this module should be loaded and enabled. If you have a NetBeans release + you may need to find another way of obtaining this open source module. + + You can check if you have this module by opening the Tools->Options dialog + and drilling down to the "Modules" list (IDE Configuration->System->Modules). + If your Modules list has an entry for "External Editor" you must make sure + it is enabled (the "Enabled" property should have the value "True"). If your + Modules list has no External Editor see the next section on |obtaining-exted|. + + ============================================================================== + 6. Obtaining the External Editor Module *obtaining-exted* + + There are 2 ways of obtaining the External Editor module. The easiest way + is to use the NetBeans Update Center to download and install the module. + Unfortunately, some versions do not have this module in their update + center. If you cannot download via the update center you will need to + download sources and build the module. I will try and get the module + available from the NetBeans Update Center so building will be unnecesary. + Also check http://externaleditor.netbeans.org for other availability options. + + To download the External Editor sources via CVS and build your own module, + see http://externaleditor.netbeans.org and http://www.netbeans.org. + Unfortunately, this is not a trivial procedure. + + ============================================================================== + 7. Setting up NetBeans to run with Vim *netbeans-setup* + + Assuming you have loaded and enabled the NetBeans External Editor module + as described in |netbeans-preparation| all you need to do is verify that + the gvim command line is properly configured for your environment. + + Open the Tools->Options dialog and open the Editing category. Select the + External Editor. The right hand pane should contain a Properties tab and + an Expert tab. In the Properties tab make sure the "Editor Type" is set + to "Vim". In the Expert tab make sure the "Vim Command" is correct. + + You should be carefull if you change the "Vim Command". There are command + line options there which must be there for the connection to be properly + set up. You can change the command name but thats about it. If your gvim + can be found by your $PATH then the VIM Command can start with "gvim". If + you don't want gvim searched from your $PATH then hard code in the full + Unix path name. At this point you should get a gvim for any source file + you open in NetBeans. + + If some files come up in gvim and others (with different file suffixes) come + up in the default NetBeans editor you should verify the MIME type in the + Expert tab MIME Type property. NetBeans is MIME oriented and the External + Editor will only open MIME types specified in this property. + + ============================================================================== + 8. Messages *netbeans-messages* + + These messages are specific for Netbeans: + + *E463* + Region is guarded, cannot modify + Netbeans defines guarded areas in the text, which you cannot + change. + + ============================================================================== + 9. Running Vim from Netbeans *netbeans-run* + + Netbeans starts Vim with the |-nb| argument. The full form is: > + -nb:{hostname}:{addr}:{password} + + {hostname} is the name of the machine where Netbeans is running. When omitted + the environment variable "__NETBEANS_HOST" is used or the default "localhost". + + {addr} is the port number for Netbeans. When omitted the environment variable + "__NETBEANS_SOCKET" is used or the default 3219. + + {password} is the password for connecting to Netbeans. When omitted the + environment variable "__NETBEANS_VIM_PASSWORD" is used or "changeme". + + ============================================================================== + 10. Netbeans protocol *netbeans-protocol* + + The communication between Netbeans and Vim uses plain text messages. This + protocol was first designed to work with the external editor module of + Netbeans (see http://externaleditor.netbeans.org). Later it was extended to + work with Agide (A-A-P GUI IDE, see http://www.a-a-p.org). The extensions are + marked with "version 2.1". + + The messages are currently sent over a socket. Since the messages are in + plain text this protocol could also be used with any other communication + mechanism. + + 10.1 Kinds of messages |nb-messages| + 10.2 Terms |nb-terms| + 10.3 Commands |nb-commands| + 10.4 Functions and Replies |nb-functions| + 10.5 Events |nb-events| + 10.6 Special messages |nb-special| + + + 10.1 Kinds of messages *nb-messages* + + There are four kinds of messages: + + kind direction comment ~ + Command IDE -> editor no reply necessary + Function IDE -> editor editor must send back a reply + Reply editor -> IDE only in response to a Function + Event editor -> IDE no reply necessary + + The messages are sent as a single line with a terminating newline character. + Arguments are separated by a single space. The first item of the message + depends on the kind of message: + + kind first item example ~ + Command bufID:name!seqno 11:showBalloon!123 "text" + Function bufID:name/seqno 11:getLength/123 + Reply seqno 123 5000 + Event bufID:name=123 11:keyCommand=123 "S-F2" + + + 10.2 Terms *nb-terms* + + bufID Buffer number. A message may be either for a specific buffer + or generic. Generic messages use a bufID of zero. NOTE: this + buffer ID is assigned by the IDE, it is not Vim's buffer + number. The bufID must be a sequentially rising number, + starting at one. + + seqno The IDE uses a sequence number for Commands and Functions. A + Reply must use the sequence number of the Function that it is + associated with. A zero sequence number can be used for + Events (the seqno of the last received Command or Function can + also be used). + + string Argument in double quotes. Text is in UTF-8 encoding. This + means ASCII is passed as-is. Special characters are + represented with a backslash: + \" double quote + \n newline + \r carriage-return + \t tab (optional, also works literally) + \\ backslash + NUL bytes are not allowed! + + boolean Argument with two possible values: + T true + F false + + number Argument with a decimal number. + + optnum Argument with either a decimal number or "none" (without the + quotes). + + offset A number argument that indicates a byte position in a buffer. + The first byte has offset zero. Line breaks are counted for + how they appear in the file (CR/LF counts for two bytes). + Note that a multi-byte character is counted for the number of + bytes it takes. + + lnum/col Argument with a line number and column number position. The + line number starts with one, the column is the byte position, + starting with zero. Note that a multi-byte character counts + for several columns. + + pathname String argument: file name with full path. + + + 10.3 Commands *nb-commands* + + actionMenuItem Not implemented. + + actionSensitivity + Not implemented. + + addAnno serNum typeNum off len + Place an annotation in this buffer. + Arguments: + serNum number serial number of this placed + annotation, used to be able to remove + it + typeNum number sequence number of the annotation + defined with defineAnnoType for this + buffer + off number offset where annotion is to be placed + len number not used + In version 2.1 "lnum/col" can be used instead of "off". + + balloonResult text + Not implemented. + + close Close the buffer. This leaves us without current buffer, very + dangerous to use! + + create Not implemented. + + defineAnnoType typeNum typeName tooltip glyphFile fg bg + Define a type of annotation for this buffer. + Arguments: + typeNum number sequence number (not really used) + typeName string name that identifies this annotation + tooltip string not used + glyphFile string name of icon file + fg optnum foreground color for line highlighting + bg optnum background color for line highlighting + Vim will define a sign for the annotation. + When both "fg" and "bg" are "none" no line highlighting is + used (new in version 2.1). + When "glyphFile" is empty, no text sign is used (new in + version 2.1). + When "glyphFile" is two characters long, a text sign is + defined (new in version 2.1). + Note: the annotations will be defined in sequence, and the + sequence number is later used with addAnno. + + editFile pathname + Set the name for the buffer and edit the file "pathname", a + string argument. + Normal way for the IDE to tell the editor to edit a file. If + the IDE is going to pass the file text to the editor use these + commands instead: + setFullName + insert + initDone + New in version 2.1. + + enableBalloonEval + Not implemented. + + endAtomic End an atomic operation. The changes between "startAtomic" + and "endAtomic" can be undone as one operation. But it's not + implemented yet. Redraw when necessary. + + guard off len + Mark an area in the buffer as guarded. This means it cannot + be edited. "off" and "len" are numbers and specify the text + to be guarded. + + initDone Mark the buffer as ready for use. Implicitly makes the buffer + the current buffer. Fires the BufReadPost autocommand event. + + moveAnnoToFront serNum + Not implemented. + + putBufferNumber pathname + Associate a buffer number with the Vim buffer by the name + "pathname", a string argument. To be used when the editor + repored editing another file to the IDE and the IDE needs to + tell the editor what buffer number it will use for this file. + Also marks the buffer as initialized. + New in version 2.1. + + raise Bring the editor to the foreground. + New in version 2.1. + + removeAnno serNum + Remove a previously place annotation for this buffer. + "serNum" is the same number used in addAnno. + + setAsUser Not implemented. + + setBufferNumber pathname + Associate a buffer number with Vim buffer by the name + "pathname". To be used when the editor reported editing + another file to the IDE and the IDE needs to tell the editor + what buffer number it will use for this file. + Has the side effect of making the buffer the current buffer. + See "putBufferNumber" for a more useful command. + + setContentType + Not implemented. + + setDot off Make the buffer the current buffer and set the cursor at the + specified position. + In version 2.1 "lnum/col" can be used instead of "off". + + setExitDelay seconds + Set the delay for exiting to "seconds", a number. + This delay is used to give the IDE a chance to handle things + before really exiting. The default delay is two seconds. + New in version 2.1. + + setFullName pathname + Set the file name to be used for a buffer to "pathname", a + string argument. + Used when the IDE wants to edit a file under control of the + IDE. This makes the buffer the current buffer, but does not + read the file. "insert" commands will be used next to set the + contents. + + setLocAndSize Not implemented. + + setMark Not implemented. + + setModified modified + When the boolean argument "modified" is "T" mark the buffer as + modified, when it is "F" mark it as unmodified. + + setReadOnly Not implemented. + + setStyle Not implemented. + + setTitle name + Set the title for the buffer to "name", a string argument. + The title is only used for Netbeans functions, not by Vim. + + setVisible visible + When the boolean argument "visible" is "T", goto the buffer. + The "F" argument does nothing. + + showBalloon text + Show a balloon (popup window) at the mouse pointer position, + containing "text", a string argument. The balloon should + disappear when the mouse is moved more than a few pixels. + New in version 2.1. + + specialKeys Not implemented. + + startAtomic Begin an atomic operation. The screen will not be updated + until "endAtomic" is given. + + startCaretListen + Not implemented. + + startDocumentListen + Mark the buffer to report changes to the IDE with the + "insert" and "remove" events. The default is to report + changes. + + stopCaretListen + Not implemented. + + stopDocumentListen + Mark the buffer to stop reporting changes to the IDE. + Opposite of startDocumentListen. + + unguard off len + Opposite of "guard", remove guarding for a text area. + + version Not implemented. + + + 10.4 Functions and Replies *nb-functions* + + getDot Not implemented. + + getLength Return the length of the buffer in bytes. + Reply example for a buffer with 5000 bytes: + 123 5000 + TODO: explain use of partial line. + + getMark Not implemented. + + getText Return the contents of the buffer as a string. + Reply example for a buffer with two lines + 123 "first line\nsecond line\n" + NOTE: docs indicate an offset and length argument, but this is + not implemented. + + insert off text + Insert "text" before position "off". "text" is a string + argument, "off" a number. + Possible replies: + 123 no problem + 123 !message failed + Note that the message in the reply is not quoted. + + remove off length + Delete "length" bytes of text at position "off". Both + arguments are numbers. + Possible replies: + 123 no problem + 123 !message failed + Note that the message in the reply is not quoted. + + + 10.5 Events *nb-events* + + balloonEval off len type + The mouse pointer rests on text for a short while. When "len" + is zero, there is no selection and the pointer is at position + "off". When "len" is non-zero the text from position "off" to + "off" + "len" is selected. + Only sent after "enableBalloonEval" was used for this buffer. + "type" is not yet defined. + Not implemented yet. + + balloonText text + Used when 'ballooneval' is set and the mouse pointer rests on + some text for a moment. "text" is a string, the text under + the mouse pointer. + New in version 2.1. + + fileClosed Not implemented. + + fileModified Not implemented. + + fileOpened pathname open modified + A file was opened by the user. + Arguments: + pathname string name of the file + open boolean always "F" + modified boolean always "F" + + geometry cols rows x y + Report the size and position of the editor window. + Arguments: + cols number number of text columns + rows number number of text rows + x number pixel position on screen + y number pixel position on screen + Only works for Motif. + + insert off text + Text "text" has been inserted in Vim at position "off". + Only fired when enabled, see "startDocumentListen". + + invokeAction Not implemented. + + keyCommand keyName + Reports a special key being pressed with name "keyName", which + is a string. + Supported key names: + F1 function key 1 + F2 function key 2 + ... + F12 function key 12 + + ' ' space (without the quotes) + ! exclamation mark + ... any other ASCII printable character + ~ tilde + + X any unrecognized key + + The key may be prepended by "C", "S" and/or "M" for Control, + Shift and Meta (Alt) modifiers. If there is a modifier a dash + is used to separate it from the key name. For example: + "C-F2". + ASCII characters are new in version 2.1. + + keyAtPos keyName lnum/col + Like "keyCommand" and also report the line number and column + of the cursor. + New in version 2.1. + + killed A file was closed by the user. Only for files that have been + assigned a number by the IDE. + + newDotAndMark off off + Reports the position of the cursor being at "off" bytes into + the buffer. Only sent just before a "keyCommand" event. + + quit Not implemented. + + remove off len + Text was deleted in Vim at position "off" with byte length + "len". + Only fired when enabled, see "startDocumentListen". + + revert Not implemented. + + save The buffer has been saved and is now unmodified. + Only fired when enabled, see "startDocumentListen". + + startupDone The editor has finished its startup work and is ready for + editing files. + New in version 2.1. + + unmodified The buffer is now unmodified. + Only fired when enabled, see "startDocumentListen". + + version vers Report the version of the interface implementation. Vim + reports "2.1" (including the quotes). + + + 10.6 Special messages *nb-special* + + These messages do not follow the style of the messages above. They are + terminated by a newline character. + + ACCEPT Not used. + + AUTH password editor -> IDE: First message that the editor sends to the IDE. + Must contain the password for the socket server, as specified + with the |-nb| argument. No quotes are used! + + DISCONNECT IDE -> editor: break the connection. The editor will exit. + The IDE must only send this message when there are no unsaved + changes! + + REJECT Not used. + + ============================================================================== + 11. Known problems *netbeans-problems* + + NUL bytes are not possible. For editor -> IDE they will appear as NL + characters. For IDE -> editor they cannot be inserted. + + + vim:tw=78:ts=8:ft=help:norl: *** ../vim61.365/runtime/doc/options.txt Thu Jan 9 21:50:31 2003 --- runtime/doc/options.txt Sat Mar 8 16:10:42 2003 *************** *** 1,4 **** ! *options.txt* For Vim version 6.1. Last change: 2003 Jan 08 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *options.txt* For Vim version 6.1. Last change: 2003 Mar 08 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 586,591 **** --- 592,610 ---- mode) and have default second language Farsi or Hebrew (right-to-left mode). See |farsi.txt|. + *'autochdir'* *'acd'* *'noatuochdir'* *'noacd'* + 'autochdir' 'acd' boolean (default off) + global + {not in Vi} + {only available when compiled with the + |+netbeans_intg| feature} + When on, vim will change its value for the current working directory + whenever you open a file, switch buffers, delete a buffer or + open/close a window. It will change to the directory containing the + file which was opened or selected. This option is provided for + backward compatibility with the vim released with Sun ONE Studio 4 + Enterprise Edition. + *'autoindent'* *'ai'* *'noautoindent'* *'noai'* 'autoindent' 'ai' boolean (default off) local to buffer *************** *** 850,856 **** global {not in Vi} {only available when compiled with the |+balloon_eval| ! and |+sun_workshop| features} Switch on the |balloon-eval| functionality. *'binary'* *'bin'* *'nobinary'* *'nobin'* --- 865,871 ---- global {not in Vi} {only available when compiled with the |+balloon_eval| ! and |+sun_workshop| or |+netbeans_intg| features} Switch on the |balloon-eval| functionality. *'binary'* *'bin'* *'nobinary'* *'nobin'* *** ../vim61.365/runtime/doc/various.txt Fri Mar 22 21:18:42 2002 --- runtime/doc/various.txt Sat Feb 15 23:32:54 2003 *************** *** 1,4 **** ! *various.txt* For Vim version 6.1. Last change: 2002 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *various.txt* For Vim version 6.1. Last change: 2003 Feb 15 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 286,291 **** --- 294,300 ---- B *+multi_byte* Korean and other languages |multibyte| *+multi_byte_ime* Win32 input method for multibyte chars |multibyte-ime| N *+multi_lang* non-English language support |multi-lang| + m *+netbeans_intg* |netbeans| m *+ole* Win32 GUI only: |ole-interface| *+osfiletype* Support for the 'osfiletype' option and filetype checking in automatic commands. |autocmd-osfiletypes| *************** *** 303,309 **** m *+sniff* SniFF interface (no docs available...) N *+statusline* Options 'statusline', 'rulerformat' and special formats of 'titlestring' and 'iconstring' ! *+sun_workshop* |workshop| N *+syntax* Syntax highlighting |syntax| *+system()* Unix only: opposite of |+fork| N *+tag_binary* binary searching in tags file |tag-binary-search| --- 312,318 ---- m *+sniff* SniFF interface (no docs available...) N *+statusline* Options 'statusline', 'rulerformat' and special formats of 'titlestring' and 'iconstring' ! m *+sun_workshop* |workshop| N *+syntax* Syntax highlighting |syntax| *+system()* Unix only: opposite of |+fork| N *+tag_binary* binary searching in tags file |tag-binary-search| *** ../vim61.365/src/Makefile Mon Feb 3 21:48:50 2003 --- src/Makefile Fri Mar 7 19:34:32 2003 *************** *** 350,358 **** # Uncomment this when you want to include the Cscope interface. #CONF_OPT_CSCOPE = --enable-cscope ! # WORKShOP - Sun Visual Workshop interface. Only works with Motif! #CONF_OPT_WORKSHOP = --enable-workshop # SNIFF - Include support for SNiFF+. #CONF_OPT_SNIFF = --enable-sniff --- 352,364 ---- # Uncomment this when you want to include the Cscope interface. #CONF_OPT_CSCOPE = --enable-cscope ! # WORKSHOP - Sun Visual Workshop interface. Only works with Motif! #CONF_OPT_WORKSHOP = --enable-workshop + # NETBEANS - NetBeans interface. Only works with Motif, GTK, and gnome. + # Motif version must have XPM libraries (see |workshop-xpm|). + # CONF_OPT_NETBEANS = --enable-netbeans + # SNIFF - Include support for SNiFF+. #CONF_OPT_SNIFF = --enable-sniff *************** *** 1201,1207 **** EXTRA_SRC = hangulin.c auto/if_perl.c if_perlsfio.c if_python.c if_tcl.c \ if_ruby.c if_sniff.c gui_beval.c \ ! workshop.c wsdebug.c integration.c # All sources, also the ones that are not configured ALL_SRC = $(BASIC_SRC) $(ALL_GUI_SRC) $(EXTRA_SRC) --- 1211,1217 ---- EXTRA_SRC = hangulin.c auto/if_perl.c if_perlsfio.c if_python.c if_tcl.c \ if_ruby.c if_sniff.c gui_beval.c \ ! workshop.c wsdebug.c integration.c netbeans.c # All sources, also the ones that are not configured ALL_SRC = $(BASIC_SRC) $(ALL_GUI_SRC) $(EXTRA_SRC) *************** *** 1210,1216 **** # checks more, but may not work well for checking a GUI that wasn't configured. # The perl sources also don't work well with lint. LINT_SRC = $(BASIC_SRC) $(GUI_SRC) $(HANGULIN_SRC) $(PYTHON_SRC) $(TCL_SRC) \ ! $(SNIFF_SRC) $(WORKSHOP_SRC) $(WSDEBUG_SRC) #LINT_SRC = $(SRC) #LINT_SRC = $(ALL_SRC) --- 1220,1226 ---- # checks more, but may not work well for checking a GUI that wasn't configured. # The perl sources also don't work well with lint. LINT_SRC = $(BASIC_SRC) $(GUI_SRC) $(HANGULIN_SRC) $(PYTHON_SRC) $(TCL_SRC) \ ! $(SNIFF_SRC) $(WORKSHOP_SRC) $(WSDEBUG_SRC) $(NETBEANS_SRC) #LINT_SRC = $(SRC) #LINT_SRC = $(ALL_SRC) *************** *** 1264,1269 **** --- 1274,1280 ---- $(RUBY_OBJ) \ $(OS_EXTRA_OBJ) \ $(WORKSHOP_OBJ) \ + $(NETBEANS_OBJ) \ $(WSDEBUG_OBJ) PRO_AUTO = \ *************** *** 1313,1318 **** --- 1324,1330 ---- window.pro \ gui_beval.pro \ workshop.pro \ + netbeans.pro \ $(ALL_GUI_PRO) \ $(TCL_PRO) *************** *** 1343,1349 **** $(CONF_OPT_CSCOPE) $(CONF_OPT_MULTIBYTE) $(CONF_OPT_INPUT) \ $(CONF_OPT_OUTPUT) $(CONF_OPT_GPM) $(CONF_OPT_WORKSHOP) \ $(CONF_OPT_SNIFF) $(CONF_OPT_FEAT) $(CONF_TERM_LIB) \ ! $(CONF_OPT_COMPBY) $(CONF_ARGS) # Use "make reconfig" to rerun configure without cached values. # When config.h changes, most things will be recompiled automatically. --- 1355,1362 ---- $(CONF_OPT_CSCOPE) $(CONF_OPT_MULTIBYTE) $(CONF_OPT_INPUT) \ $(CONF_OPT_OUTPUT) $(CONF_OPT_GPM) $(CONF_OPT_WORKSHOP) \ $(CONF_OPT_SNIFF) $(CONF_OPT_FEAT) $(CONF_TERM_LIB) \ ! $(CONF_OPT_COMPBY) $(CONF_OPT_ACL) $(CONF_OPT_NETBEANS) \ ! $(CONF_ARGS) # Use "make reconfig" to rerun configure without cached values. # When config.h changes, most things will be recompiled automatically. *************** *** 2187,2192 **** --- 2200,2207 ---- objects/wsdebug.o: wsdebug.c $(CCC) -o $@ wsdebug.c + objects/netbeans.o: netbeans.c + $(CCC) -o $@ netbeans.c Makefile: @echo The name of the makefile MUST be "Makefile" (with capital M)!!!! *************** *** 2418,2420 **** --- 2433,2438 ---- objects/integration.o: integration.c vim.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h option.h ex_cmds.h proto.h globals.h farsi.h integration.h + objects/netbeans.o: netbeans.c vim.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h structs.h regexp.h \ + gui.h option.h ex_cmds.h proto.h globals.h farsi.h version.h *** ../vim61.365/src/auto/configure Tue Feb 25 21:50:44 2003 --- src/auto/configure Mon Feb 17 12:00:06 2003 *************** *** 42,47 **** --- 42,49 ---- ac_help="$ac_help --enable-workshop Include Sun Visual Workshop support." ac_help="$ac_help + --enable-netbeans Include NetBeans integration support." + ac_help="$ac_help --enable-sniff Include Sniff interface." ac_help="$ac_help --enable-multibyte Include multibyte editing support." *************** *** 2048,2055 **** fi fi echo $ac_n "checking --enable-sniff argument""... $ac_c" 1>&6 ! echo "configure:2038: checking --enable-sniff argument" >&5 # Check whether --enable-sniff or --disable-sniff was given. if test "${enable_sniff+set}" = set; then enableval="$enable_sniff" --- 2050,2133 ---- fi fi + echo $ac_n "checking --enable-netbeans argument""... $ac_c" 1>&6 + echo "configure:2055: checking --enable-netbeans argument" >&5 + # Check whether --enable-netbeans or --disable-netbeans was given. + if test "${enable_netbeans+set}" = set; then + enableval="$enable_netbeans" + : + else + enable_netbeans="no" + fi + + echo "$ac_t""$enable_netbeans" 1>&6 + if test "$enable_netbeans" = "yes"; then + echo $ac_n "checking whether compiling netbeans integration is possible""... $ac_c" 1>&6 + echo "configure:2067: checking whether compiling netbeans integration is possible" >&5 + cat > conftest.$ac_ext < + #include + #include + #include + #include + #include + #include + #include + #include + /* Check use of vsnprintf() */ + void warn(char *fmt, ...); + void warn(char *fmt, ...) + { + va_list ap; char *buf = NULL; + va_start(ap, fmt); + vsnprintf(buf, 100, fmt, ap); + va_end(ap); + } + /* Check bitfields */ + struct nbbuf { + unsigned int initDone:1; + ushort signmaplen; + }; + + int main() { + + /* Check creating a socket. */ + struct sockaddr_in server; + (void)socket(AF_INET, SOCK_STREAM, 0); + (void)htons(100); + (void)gethostbyname("microsoft.com"); + if (errno == ECONNREFUSED) + (void)connect(1, (struct sockaddr *)&server, sizeof(server)); + + ; return 0; } + EOF + if { (eval echo configure:2108: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6; enable_netbeans="no" + fi + rm -f conftest* + fi + if test "$enable_netbeans" = "yes"; then + cat >> confdefs.h <<\EOF + #define FEAT_NETBEANS_INTG 1 + EOF + + NETBEANS_SRC="netbeans.c" + + NETBEANS_OBJ="objects/netbeans.o" + + fi + echo $ac_n "checking --enable-sniff argument""... $ac_c" 1>&6 ! echo "configure:2131: checking --enable-sniff argument" >&5 # Check whether --enable-sniff or --disable-sniff was given. if test "${enable_sniff+set}" = set; then enableval="$enable_sniff" *************** *** 7399,7404 **** --- 7477,7484 ---- s%@RUBY_LIBS@%$RUBY_LIBS%g s%@WORKSHOP_SRC@%$WORKSHOP_SRC%g s%@WORKSHOP_OBJ@%$WORKSHOP_OBJ%g + s%@NETBEANS_SRC@%$NETBEANS_SRC%g + s%@NETBEANS_OBJ@%$NETBEANS_OBJ%g s%@SNIFF_SRC@%$SNIFF_SRC%g s%@SNIFF_OBJ@%$SNIFF_OBJ%g s%@xmkmfpath@%$xmkmfpath%g *** ../vim61.365/src/buffer.c Mon Feb 24 11:29:14 2003 --- src/buffer.c Sat Mar 8 16:59:52 2003 *************** *** 112,121 **** /* mark cursor position as being invalid */ changed_line_abv_curs(); ! if (curbuf->b_ffname != NULL) { retval = readfile(curbuf->b_ffname, curbuf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, READ_NEW); /* Help buffer is filtered. */ if (curbuf->b_help) fix_help_buffer(); --- 112,133 ---- /* mark cursor position as being invalid */ changed_line_abv_curs(); ! if (curbuf->b_ffname != NULL ! #ifdef FEAT_NETBEANS_INTG ! && netbeansReadFile ! #endif ! ) { + #ifdef FEAT_NETBEANS_INTG + int oldFire = netbeansFireChanges; + + netbeansFireChanges = 0; + #endif retval = readfile(curbuf->b_ffname, curbuf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, READ_NEW); + #ifdef FEAT_NETBEANS_INTG + netbeansFireChanges = oldFire; + #endif /* Help buffer is filtered. */ if (curbuf->b_help) fix_help_buffer(); *************** *** 371,376 **** --- 383,399 ---- return; #endif + #ifdef FEAT_NETBEANS_INTG + if (usingNetbeans) + netbeans_file_closed(buf); + #endif + #if defined(FEAT_NETBEANS_INTG) || defined(FEAT_SUN_WORKSHOP) + /* Change directories when the acd option is set on. */ + if (p_acd && curbuf->b_ffname != NULL + && vim_chdirfile(curbuf->b_ffname) == OK) + shorten_fnames(TRUE); + #endif + /* * Remove the buffer from the list. */ *************** *** 432,437 **** --- 455,464 ---- #endif buf->b_ml.ml_mfp = NULL; buf->b_ml.ml_flags = ML_EMPTY; /* empty buffer */ + #ifdef FEAT_NETBEANS_INTG + netbeans_deleted_all_lines(buf); + netbeansOpenFile = 0; /* reset in netbeans_file_opened() */ + #endif } /* *************** *** 649,654 **** --- 676,684 ---- int bnr; /* buffer number */ char_u *p; + #ifdef FEAT_NETBEANS_INTG + netbeansCloseFile = 1; + #endif if (addr_count == 0) { (void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit); *************** *** 743,748 **** --- 773,782 ---- } } + #ifdef FEAT_NETBEANS_INTG + netbeansCloseFile = 0; + #endif + return errormsg; } *************** *** 1203,1212 **** if (curwin->w_topline == 1) /* when autocmds didn't change it */ #endif scroll_cursor_halfway(FALSE); /* redisplay at correct position */ ! #ifdef FEAT_SUN_WORKSHOP ! if (usingSunWorkShop && vim_chdirfile(buf->b_ffname) == OK) shorten_fnames(TRUE); #endif #ifdef FEAT_KEYMAP if (curbuf->b_kmap_state & KEYMAP_INIT) keymap_init(); --- 1237,1249 ---- if (curwin->w_topline == 1) /* when autocmds didn't change it */ #endif scroll_cursor_halfway(FALSE); /* redisplay at correct position */ ! ! #if defined(FEAT_NETBEANS_INTG) || defined(FEAT_SUN_WORKSHOP) ! /* Change directories when the acd option is set on. */ ! if (p_acd && vim_chdirfile(buf->b_ffname) == OK) shorten_fnames(TRUE); #endif + #ifdef FEAT_KEYMAP if (curbuf->b_kmap_state & KEYMAP_INIT) keymap_init(); *************** *** 4292,4297 **** --- 4358,4368 ---- newsign->lnum = lnum; newsign->typenr = typenr; newsign->next = next; + #ifdef FEAT_NETBEANS_INTG + newsign->prev = prev; + if (next != NULL) + next->prev = newsign; + #endif if (prev == NULL) { *************** *** 4314,4320 **** /* * Add the sign into the signlist. Find the right spot to do it though. */ ! int buf_addsign(buf, id, lnum, typenr) buf_T *buf; /* buffer to store sign in */ int id; /* sign ID */ --- 4385,4391 ---- /* * Add the sign into the signlist. Find the right spot to do it though. */ ! void buf_addsign(buf, id, lnum, typenr) buf_T *buf; /* buffer to store sign in */ int id; /* sign ID */ *************** *** 4330,4347 **** if (lnum == sign->lnum && id == sign->id) { sign->typenr = typenr; ! return sign->lnum; } ! else if (id < 0 && lnum < sign->lnum) ! { insert_sign(buf, prev, sign, id, lnum, typenr); ! return lnum; } prev = sign; } ! insert_sign(buf, prev, NULL, id, lnum, typenr); ! return lnum; } int --- 4401,4443 ---- if (lnum == sign->lnum && id == sign->id) { sign->typenr = typenr; ! return; } ! else if ( ! #ifndef FEAT_NETBEANS_INTG /* keep signs sorted by lnum */ ! id < 0 && ! #endif ! lnum < sign->lnum) ! { ! #ifdef FEAT_NETBEANS_INTG /* insert new sign at head of list for this lnum */ ! /* XXX - GRP: Is this because of sign slide problem? Or is it ! * really needed? Or is it because we allow multiple signs per ! * line? If so, should I add that feature to FEAT_SIGNS? ! */ ! while (prev != NULL && prev->lnum == lnum) ! prev = prev->prev; ! if (prev == NULL) ! sign = buf->b_signlist; ! else ! sign = prev->next; ! #endif insert_sign(buf, prev, sign, id, lnum, typenr); ! return; } prev = sign; } ! #ifdef FEAT_NETBEANS_INTG /* insert new sign at head of list for this lnum */ ! /* XXX - GRP: See previous comment */ ! while (prev != NULL && prev->lnum == lnum) ! prev = prev->prev; ! if (prev == NULL) ! sign = buf->b_signlist; ! else ! sign = prev->next; ! #endif ! insert_sign(buf, prev, sign, id, lnum, typenr); ! return; } int *************** *** 4365,4378 **** } int_u ! buf_getsigntype(buf, lnum) buf_T *buf; linenr_T lnum; { signlist_T *sign; /* a sign in a b_signlist */ for (sign = buf->b_signlist; sign != NULL; sign = sign->next) ! if (sign->lnum == lnum) return sign->typenr; return 0; } --- 4461,4484 ---- } int_u ! buf_getsigntype(buf, lnum, type) buf_T *buf; linenr_T lnum; + int type; /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */ { signlist_T *sign; /* a sign in a b_signlist */ for (sign = buf->b_signlist; sign != NULL; sign = sign->next) ! if (sign->lnum == lnum ! && (type == SIGN_ANY ! # ifdef FEAT_SIGN_ICONS ! || (type == SIGN_ICON ! && sign_get_image(sign->typenr) != NULL) ! # endif ! || (type == SIGN_TEXT ! && sign_get_text(sign->typenr) != NULL) ! || (type == SIGN_LINEHL ! && sign_get_attr(sign->typenr, TRUE) != 0))) return sign->typenr; return 0; } *************** *** 4396,4401 **** --- 4502,4511 ---- if (sign->id == id) { *lastp = next; + #ifdef FEAT_NETBEANS_INTG + if (next != NULL) + next->prev = sign->prev; + #endif lnum = sign->lnum; vim_free(sign); break; *************** *** 4448,4453 **** --- 4558,4600 ---- return 0; } + + + # if defined(FEAT_NETBEANS_INTG) || defined(PROTO) + /* see if a given type of sign exists on a specific line */ + int + buf_findsigntype_id(buf, lnum, typenr) + buf_T *buf; /* buffer whose sign we are searching for */ + linenr_T lnum; /* line number of sign */ + int typenr; /* sign type number */ + { + signlist_T *sign; /* a sign in the signlist */ + + for (sign = buf->b_signlist; sign != NULL; sign = sign->next) + if (sign->lnum == lnum && sign->typenr == typenr) + return sign->id; + + return 0; + } + + + /* return the number of icons on the given line */ + int + buf_signcount(buf, lnum) + buf_T *buf; + linenr_T lnum; + { + signlist_T *sign; /* a sign in the signlist */ + int count = 0; + + for (sign = buf->b_signlist; sign != NULL; sign = sign->next) + if (sign->lnum == lnum) + if (sign_get_image(sign->typenr) != NULL) + count++; + + return count; + } + # endif /* FEAT_NETBEANS_INTG */ void *** ../vim61.365/src/config.h.in Tue Feb 25 21:50:44 2003 --- src/config.h.in Sun Feb 16 18:31:10 2003 *************** *** 346,351 **** --- 334,342 ---- /* Define if you want to include Sun Visual Workshop support. */ #undef FEAT_SUN_WORKSHOP + + /* Define if you want to include NetBeans integration. */ + #undef FEAT_NETBEANS_INTG /* Define default global runtime path */ #undef RUNTIME_GLOBAL *** ../vim61.365/src/config.mk.in Fri Aug 24 12:42:08 2001 --- src/config.mk.in Thu Feb 13 16:35:00 2003 *************** *** 64,69 **** --- 64,72 ---- WORKSHOP_SRC = @WORKSHOP_SRC@ WORKSHOP_OBJ = @WORKSHOP_OBJ@ + NETBEANS_SRC = @NETBEANS_SRC@ + NETBEANS_OBJ = @NETBEANS_OBJ@ + RUBY = @vi_cv_path_ruby@ RUBY_SRC = @RUBY_SRC@ RUBY_OBJ = @RUBY_OBJ@ *** ../vim61.365/src/configure.in Tue Feb 25 21:50:44 2003 --- src/configure.in Mon Feb 17 11:59:46 2003 *************** *** 588,593 **** --- 588,644 ---- fi fi + AC_MSG_CHECKING(--enable-netbeans argument) + AC_ARG_ENABLE(netbeans, + [ --enable-netbeans Include NetBeans integration support.], , + [enable_netbeans="no"]) + AC_MSG_RESULT($enable_netbeans) + if test "$enable_netbeans" = "yes"; then + AC_MSG_CHECKING(whether compiling netbeans integration is possible) + AC_TRY_COMPILE([ + #include + #include + #include + #include + #include + #include + #include + #include + #include + /* Check use of vsnprintf() */ + void warn(char *fmt, ...); + void warn(char *fmt, ...) + { + va_list ap; char *buf = NULL; + va_start(ap, fmt); + vsnprintf(buf, 100, fmt, ap); + va_end(ap); + } + /* Check bitfields */ + struct nbbuf { + unsigned int initDone:1; + ushort signmaplen; + }; + ], [ + /* Check creating a socket. */ + struct sockaddr_in server; + (void)socket(AF_INET, SOCK_STREAM, 0); + (void)htons(100); + (void)gethostbyname("microsoft.com"); + if (errno == ECONNREFUSED) + (void)connect(1, (struct sockaddr *)&server, sizeof(server)); + ], + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no); enable_netbeans="no") + fi + if test "$enable_netbeans" = "yes"; then + AC_DEFINE(FEAT_NETBEANS_INTG) + NETBEANS_SRC="netbeans.c" + AC_SUBST(NETBEANS_SRC) + NETBEANS_OBJ="objects/netbeans.o" + AC_SUBST(NETBEANS_OBJ) + fi + AC_MSG_CHECKING(--enable-sniff argument) AC_ARG_ENABLE(sniff, [ --enable-sniff Include Sniff interface.], , *** ../vim61.365/src/edit.c Tue Feb 25 21:13:03 2003 --- src/edit.c Thu Feb 27 12:45:25 2003 *************** *** 789,794 **** --- 789,803 ---- need_start_insertmode = TRUE; goto doESCkey; + #ifdef FEAT_NETBEANS_INTG + case K_F21: + ++no_mapping; /* don't map the next key hits */ + i = safe_vgetc(); + --no_mapping; + netbeans_keycommand(i); + break; + #endif + /* an escape ends input mode */ case ESC: if (echeck_abbr(ESC + ABBR_OFF)) *** ../vim61.365/src/ex_cmds.c Sun Feb 16 22:16:19 2003 --- src/ex_cmds.c Mon Feb 17 21:11:52 2003 *************** *** 2891,2898 **** foldUpdateAll(curwin); #endif ! #ifdef FEAT_SUN_WORKSHOP ! if (usingSunWorkShop && curbuf->b_ffname != NULL && vim_chdirfile(curbuf->b_ffname) == OK) shorten_fnames(TRUE); #endif --- 2891,2898 ---- foldUpdateAll(curwin); #endif ! #if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) ! if (p_acd && curbuf->b_ffname != NULL && vim_chdirfile(curbuf->b_ffname) == OK) shorten_fnames(TRUE); #endif *************** *** 3047,3059 **** if (p_im) need_start_insertmode = TRUE; ! #ifdef FEAT_SUN_WORKSHOP ! if (usingSunWorkShop && curbuf->b_ffname != NULL && vim_chdirfile(curbuf->b_ffname) == OK) shorten_fnames(TRUE); ! if (gui.in_use && curbuf != NULL && curbuf->b_fname != NULL) ! workshop_file_opened((char *)curbuf->b_ffname, curbuf->b_p_ro); #endif theend: --- 3047,3069 ---- if (p_im) need_start_insertmode = TRUE; ! #if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) ! /* Change directories when the acd option is set on. */ ! if (p_acd && curbuf->b_ffname != NULL && vim_chdirfile(curbuf->b_ffname) == OK) shorten_fnames(TRUE); ! if (gui.in_use && curbuf->b_fname != NULL) ! { ! # ifdef FEAT_SUN_WORKSHOP ! if (usingSunWorkShop) ! workshop_file_opened((char *)curbuf->b_ffname, curbuf->b_p_ro); ! # endif ! # ifdef FEAT_NETBEANS_INTG ! if (usingNetbeans) ! netbeans_file_opened((char *)curbuf->b_ffname); ! # endif ! } #endif theend: *** ../vim61.365/src/ex_docmd.c Tue Feb 25 21:41:42 2003 --- src/ex_docmd.c Sat Mar 8 13:59:20 2003 *************** *** 4944,4949 **** --- 4955,4964 ---- } #endif + #ifdef FEAT_NETBEANS_INTG + netbeansForcedQuit = eap->forceit; + #endif + /* * If there are more files or windows we won't exit. */ *** ../vim61.365/src/feature.h Fri Sep 27 19:30:44 2002 --- src/feature.h Thu Feb 13 16:56:44 2003 *************** *** 1052,1057 **** --- 1052,1059 ---- * +python Python interface: "--enable-pythoninterp" * +tcl TCL interface: "--enable-tclinterp" * +sniff Sniff interface: "--enable-sniff" + * +sun_workshop Sun Workshop integegration + * +netbeans_intg Netbeans integration */ /* *************** *** 1071,1080 **** * +signs Allow signs to be displayed to the left of text lines. * Adds the ":sign" command. */ ! #if defined(FEAT_BIG) || defined(FEAT_SUN_WORKSHOP) # define FEAT_SIGNS # if ((defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) \ ! && defined(HAVE_X11_XPM_H)) \ || (defined(WIN32) && defined(FEAT_GUI)) # define FEAT_SIGN_ICONS # endif --- 1073,1084 ---- * +signs Allow signs to be displayed to the left of text lines. * Adds the ":sign" command. */ ! #if defined(FEAT_BIG) || defined(FEAT_SUN_WORKSHOP) \ ! || defined(FEAT_NETBEANS_INTG) # define FEAT_SIGNS # if ((defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) \ ! && defined(HAVE_X11_XPM_H)) \ ! || defined(FEAT_GUI_GTK) \ || (defined(WIN32) && defined(FEAT_GUI)) # define FEAT_SIGN_ICONS # endif *************** *** 1086,1108 **** * Currently only for Athena and Motif. */ #if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) \ ! && (defined(FEAT_TOOLBAR) || defined(FEAT_SUN_WORKSHOP)) # define FEAT_BEVAL # ifndef FEAT_XFONTSET # define FEAT_XFONTSET # endif #endif ! #if defined(FEAT_SUN_WORKSHOP) /* ! * The following features are (currently) only used by Sun Visual WorkShop 6. ! * These features could be used with other integrations with debuggers so I've ! * used separate feature defines. */ # if !defined(FEAT_MENU) # define FEAT_MENU # endif /* * Use an alternative method of X input for a secondary * command input. --- 1090,1116 ---- * Currently only for Athena and Motif. */ #if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) \ ! && ( defined(FEAT_TOOLBAR) \ ! || defined(FEAT_SUN_WORKSHOP) \ ! || defined(FEAT_NETBEANS_INTG)) # define FEAT_BEVAL # ifndef FEAT_XFONTSET # define FEAT_XFONTSET # endif #endif ! #if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) /* ! * The following features are (currently) only used by Sun Visual WorkShop 6 ! * and NetBeans. These features could be used with other integrations with ! * debuggers so I've used separate feature defines. */ # if !defined(FEAT_MENU) # define FEAT_MENU # endif + #endif + #if defined(FEAT_SUN_WORKSHOP) /* * Use an alternative method of X input for a secondary * command input. *** ../vim61.365/src/fileio.c Wed Feb 26 21:12:31 2003 --- src/fileio.c Sat Mar 8 14:29:27 2003 *************** *** 1799,1805 **** --- 1799,1811 ---- /* need to delete the last line, which comes from the empty buffer */ if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) { + #ifdef FEAT_NETBEANS_INTG + netbeansFireChanges = 0; + #endif ml_delete(curbuf->b_ml.ml_line_count, FALSE); + #ifdef FEAT_NETBEANS_INTG + netbeansFireChanges = 1; + #endif --linecnt; } linecnt = curbuf->b_ml.ml_line_count - linecnt; *************** *** 3795,3800 **** --- 3805,3813 ---- { unchanged(buf, TRUE); u_unchanged(buf); + #ifdef FEAT_NETBEANS_INTG + netbeans_saved(buf); + #endif } /* *** ../vim61.365/src/globals.h Tue Nov 19 11:21:32 2002 --- src/globals.h Mon Feb 17 22:44:09 2003 *************** *** 330,335 **** --- 330,343 ---- /* "-fn" or "-font" command line argument */ EXTERN char *font_argument INIT(= NULL); + # ifdef FEAT_GUI_GTK + /* "-bg" or "-background" command line argument */ + EXTERN char *background_argument INIT(= NULL); + + /* "-fg" or "-foreground" command line argument */ + EXTERN char *foreground_argument INIT(= NULL); + # endif + /* * While executing external commands or in Ex mode, should not insert GUI * events in the input buffer: Set hold_gui_events to non-zero. *************** *** 1046,1051 **** --- 1054,1070 ---- ; #endif + #ifdef FEAT_NETBEANS_INTG + char *netbeansArg INIT(= 0); /* the -nb[:host:port:passwd] arg */ + int netbeansCloseFile INIT(= 0); /* send killed if != 0 */ + int netbeansFireChanges INIT(= 1); /* send buffer changes if != 0 */ + int netbeansForcedQuit INIT(= 0); /* don't write modified files */ + int netbeansOpenFile INIT(= 1); /* send fileOpened if != 0 */ + int netbeansReadFile INIT(= 1); /* OK to read from disk if != 0 */ + int netbeansSuppressNoLines INIT(= 0); /* don't put out "No lines in buffer" */ + int usingNetbeans INIT(= 0); /* set if -nb flag is used */ + #endif + /* * The error messages that can be shared are included here. * Excluded are errors that are only used once and debugging messages. *************** *** 1164,1169 **** --- 1183,1191 ---- #endif #ifdef FEAT_CLIENTSERVER EXTERN char_u e_invexprmsg[] INIT(=N_("E449: Invalid expression received")); + #endif + #ifdef FEAT_NETBEANS_INTG + EXTERN char_u e_guarded[] INIT(=N_("E463: Region is guarded, cannot modify")); #endif #ifdef MACOS_X_UNIX EXTERN short disallow_gui INIT(= FALSE); *** ../vim61.365/src/gui.c Thu Feb 20 21:36:44 2003 --- src/gui.c Wed Feb 19 10:51:34 2003 *************** *** 1535,1540 **** --- 1536,1544 ---- #endif #ifdef FEAT_SIGN_ICONS && s[0] != SIGN_BYTE + # ifdef FEAT_NETBEANS_INTG + && s[0] != MULTISIGN_BYTE + # endif #endif ) { *************** *** 1579,1584 **** --- 1583,1591 ---- #endif #ifdef FEAT_SIGN_ICONS || *p == SIGN_BYTE + # ifdef FEAT_NETBEANS_INTG + || *p == MULTISIGN_BYTE + # endif #endif )) { *************** *** 1774,1779 **** --- 1781,1789 ---- int col = gui.col; #ifdef FEAT_SIGN_ICONS int draw_sign = FALSE; + # ifdef FEAT_NETBEANS_INTG + int multi_sign = FALSE; + # endif #endif if (len < 0) *************** *** 1782,1789 **** return OK; #ifdef FEAT_SIGN_ICONS ! if (*s == SIGN_BYTE) { /* draw spaces instead */ s = (char_u *)" "; if (len == 1 && col > 0) --- 1792,1807 ---- return OK; #ifdef FEAT_SIGN_ICONS ! if (*s == SIGN_BYTE ! # ifdef FEAT_NETBEANS_INTG ! || *s == MULTISIGN_BYTE ! # endif ! ) { + # ifdef FEAT_NETBEANS_INTG + if (*s == MULTISIGN_BYTE) + multi_sign = TRUE; + # endif /* draw spaces instead */ s = (char_u *)" "; if (len == 1 && col > 0) *************** *** 2070,2075 **** --- 2088,2097 ---- if (draw_sign) /* Draw the sign on top of the spaces. */ gui_mch_drawsign(gui.row, col, gui.highlight_mask); + # ifdef FEAT_NETBEANS_INTG + if (multi_sign) + netbeans_draw_multisign_indicator(gui.row); + # endif #endif return OK; *** ../vim61.365/src/gui_beval.c Wed Oct 24 14:12:09 2001 --- src/gui_beval.c Mon Mar 3 17:35:20 2003 *************** *** 137,144 **** removeEventHandler(beval); } ! #if defined(FEAT_SUN_WORKSHOP) || defined(PROTO) ! Boolean gui_mch_get_beval_info(beval, filename, line, text, idx) BalloonEval *beval; char_u **filename; --- 137,149 ---- removeEventHandler(beval); } ! #if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) || defined(PROTO) ! /* ! * Get the text and position to be evaluated for "beval". ! * When "usingNetbeans" is set the returned text is in allocated memory. ! * Returns OK or FAIL. ! */ ! int gui_mch_get_beval_info(beval, filename, line, text, idx) BalloonEval *beval; char_u **filename; *************** *** 151,156 **** --- 156,162 ---- char_u *lbuf; linenr_T lnum; + *text = NULL; row = Y_2_ROW(beval->y); col = X_2_COL(beval->x); wp = mouse_find_win(&row, &col); *************** *** 165,181 **** if (col <= win_linetabsize(wp, lbuf, (colnr_T)MAXCOL)) { /* Not past end of line. */ *filename = wp->w_buffer->b_ffname; *line = (int)lnum; *text = lbuf; *idx = col; beval->ts = wp->w_buffer->b_p_ts; ! return True; } } } ! return False; } /* --- 171,245 ---- if (col <= win_linetabsize(wp, lbuf, (colnr_T)MAXCOL)) { /* Not past end of line. */ + # ifdef FEAT_NETBEANS_INTG + if (usingNetbeans) + { + /* For Netbeans we get the relevant part of the line + * instead of the whole line. */ + int len; + pos_T *spos = NULL, *epos = NULL; + + if (VIsual_active) + { + if (lt(VIsual, curwin->w_cursor)) + { + spos = &VIsual; + epos = &curwin->w_cursor; + } + else + { + spos = &curwin->w_cursor; + epos = &VIsual; + } + } + + col = vcol2col(wp, lnum, col) - 1; + + if (VIsual_active + && wp->w_buffer == curwin->w_buffer + && (lnum == spos->lnum + ? col >= spos->col + : lnum > spos->lnum) + && (lnum == epos->lnum + ? col <= epos->col + : lnum < epos->lnum)) + { + /* Visual mode and pointing to the line with the + * Visual selection: return selected text, with a + * maximum of one line. */ + if (spos->lnum != epos->lnum || spos->col == epos->col) + return FAIL; + + lbuf = ml_get_buf(curwin->w_buffer, VIsual.lnum, FALSE); + lbuf = vim_strnsave(lbuf + spos->col, + epos->col - spos->col + (*p_sel != 'e')); + lnum = spos->lnum; + col = spos->col; + } + else + { + /* Find the word under the cursor. */ + ++emsg_off; + len = find_ident_at_pos(wp, lnum, (colnr_T)col, &lbuf, + FIND_IDENT + FIND_STRING); + --emsg_off; + if (len == 0) + return FAIL; + lbuf = vim_strnsave(lbuf, len); + } + } + # endif *filename = wp->w_buffer->b_ffname; *line = (int)lnum; *text = lbuf; *idx = col; beval->ts = wp->w_buffer->b_p_ts; ! return OK; } } } ! return FAIL; } /* *************** *** 425,431 **** #ifdef FEAT_GUI_MOTIF XmString s; ! s = XmStringCreateLocalized((char *)beval->msg); { XmFontList fl; --- 489,501 ---- #ifdef FEAT_GUI_MOTIF XmString s; ! /* For the callback function we parse NL characters to create a ! * multi-line label. This doesn't work for all languages, but ! * XmStringCreateLocalized() doesn't do multi-line labels... */ ! if (beval->msgCB != NULL) ! s = XmStringCreateLtoR((char *)beval->msg, XmFONTLIST_DEFAULT_TAG); ! else ! s = XmStringCreateLocalized((char *)beval->msg); { XmFontList fl; *** ../vim61.365/src/gui_gtk_x11.c Sun Feb 16 22:13:38 2003 --- src/gui_gtk_x11.c Mon Feb 17 22:43:03 2003 *************** *** 253,263 **** {"-geometry", TRUE}, {"-reverse", FALSE}, {"-rv", FALSE}, ! #if 0 /* TBD */ {"-bg", TRUE}, {"-background", TRUE}, {"-fg", TRUE}, {"-foreground", TRUE}, {"-boldfont", TRUE}, {"-italicfont", TRUE}, {"+reverse", FALSE}, --- 253,264 ---- {"-geometry", TRUE}, {"-reverse", FALSE}, {"-rv", FALSE}, ! {"-bg", TRUE}, {"-background", TRUE}, {"-fg", TRUE}, {"-foreground", TRUE}, + #if 0 /* TBD */ {"-boldfont", TRUE}, {"-italicfont", TRUE}, {"+reverse", FALSE}, *************** *** 293,299 **** "--disable-sound", "--enable-sound", "--espeaker=", ! "--version", "-?", "--help", "--usage", --- 294,300 ---- "--disable-sound", "--enable-sound", "--espeaker=", ! /* "--version", */ "-?", "--help", "--usage", *************** *** 364,369 **** --- 365,380 ---- { gui.geom = (char_u *)g_strdup((const char *)argv[arg + 1]); } + else if ((strcmp("-background", argv[arg]) == 0 + || strcmp("-bg", argv[arg]) == 0) && arg + 1 < *argc) + { + background_argument = g_strdup((const char *)argv[arg + 1]); + } + else if ((strcmp("-foreground", argv[arg]) == 0 + || strcmp("-fg", argv[arg]) == 0) && arg + 1 < *argc) + { + foreground_argument = g_strdup((const char *)argv[arg + 1]); + } #ifndef FEAT_GUI_GNOME /* Found match in table, so move it into gui_argv */ *************** *** 385,390 **** --- 396,419 ---- } } } + #ifdef FEAT_NETBEANS_INTG + else if (strncmp("-nb", argv[arg], 3) == 0) + { + usingNetbeans++; + gui.dofork = FALSE; /* don't fork() when starting GUI */ + netbeansArg = argv[arg]; + mch_memmove(&argv[arg], &argv[arg + 1], + (--*argc - arg) * sizeof(char *)); + } + + else if (strcmp("-xrm", argv[arg]) == 0 + || strcmp("-mf", argv[arg]) == 0) + { + /* remove these arguments for now */ + mch_memmove(&argv[arg], &argv[arg + 2], + ((*argc=*argc-2) - arg) * sizeof(char *)); + } + #endif else ++arg; } *************** *** 2040,2045 **** --- 2069,2079 ---- /* Pretend we don't have input focus, we will get an event if we do. */ gui.in_focus = FALSE; + #ifdef FEAT_NETBEANS_INTG + if (usingNetbeans) + netbeans_gtk_connect(); + # endif + return OK; } *************** *** 2196,2212 **** gui.def_back_pixel = gui_get_color((char_u *)"White"); } /* Get the colors from the "Normal" and "Menu" group (set in syntax.c or ! * in a vimrc file) ! */ set_normal_colors(); /* Check that none of the colors are the same as the background color */ gui_check_colors(); /* Get the colors for the highlight groups (gui_check_colors() might have ! * changed them). ! */ highlight_gui_started(); /* re-init colors and fonts */ gtk_signal_connect(GTK_OBJECT(gui.mainwin), "destroy", --- 2230,2250 ---- gui.def_back_pixel = gui_get_color((char_u *)"White"); } + if (background_argument) + gui.def_back_pixel = gui_get_color((char_u *)background_argument); + + if (foreground_argument) + gui.def_norm_pixel = gui_get_color((char_u *)foreground_argument); + /* Get the colors from the "Normal" and "Menu" group (set in syntax.c or ! * in a vimrc file) */ set_normal_colors(); /* Check that none of the colors are the same as the background color */ gui_check_colors(); /* Get the colors for the highlight groups (gui_check_colors() might have ! * changed them). */ highlight_gui_started(); /* re-init colors and fonts */ gtk_signal_connect(GTK_OBJECT(gui.mainwin), "destroy", *************** *** 3842,3844 **** --- 3879,3949 ---- last_shape = shape; } #endif + + #if defined(FEAT_SIGN_ICONS) || defined(PROTO) + + /* Signs are currently always 2 chars wide. Hopefully the font is big enough + * to provide room for the bitmap! */ + # define SIGN_WIDTH (gui.char_width * 2) + # define SIGN_HEIGHT (gui.char_height) + + #if 0 /* not used */ + void + gui_mch_clearsign(row) + int row; + { + if (gui.in_use) + XClearArea(gui.dpy, gui.wid, 0, TEXT_Y(row) - gui.char_height, + SIGN_WIDTH, gui.char_height, FALSE); + } + #endif + + void + gui_mch_drawsign(row, col, typenr) + int row; + int col; + int typenr; + { + GdkPixmap *sign = 0; + gint width; + gint height; + + if (gui.in_use && (sign = (GdkPixmap *)sign_get_image(typenr)) != NULL) + { + gdk_window_get_size(sign, &width, &height); + gdk_window_clear_area(gui.drawarea->window, TEXT_X(col), + TEXT_Y(row) - height, + SIGN_WIDTH, gui.char_height); + gdk_draw_pixmap(gui.drawarea->window, gui.text_gc, sign, 0, 0, + TEXT_X(col) + (SIGN_WIDTH - width) / 2, + TEXT_Y(row) - (SIGN_HEIGHT - height) / 2 - height, + width, height); + } + } + + void * + gui_mch_register_sign(signfile) + char_u *signfile; + { + GdkPixmap *sign; + + sign = NULL; + if (signfile[0] != NUL && signfile[0] != '-') + { + sign = gdk_pixmap_create_from_xpm(gui.drawarea->window, NULL, NULL, + (char *)signfile); + if (sign == NULL) + EMSG(_("E255: Couldn't read in sign data!")); + } + + return (void *)sign; + } + + /*ARGSUSED*/ + void + gui_mch_destroy_sign(sign) + void *sign; + { + /* ??? */ + } + #endif /* FEAT_SIGN_ICONS */ *** ../vim61.365/src/gui_x11.c Sun Feb 16 22:13:38 2003 --- src/gui_x11.c Tue Mar 4 22:21:36 2003 *************** *** 656,661 **** --- 656,670 ---- workshop_frame_moved(rec.x, rec.y, rec.width, rec.height); } #endif + #ifdef FEAT_NETBEANS_INTG + if (usingNetbeans) + { + XRectangle rec; + + shellRectangle(w, &rec); + netbeans_frame_moved(rec.x, rec.y); + } + #endif #ifdef FEAT_XIM xim_set_preedit(); #endif *************** *** 1169,1174 **** --- 1179,1195 ---- } else #endif + #ifdef FEAT_NETBEANS_INTG + if (strncmp("-nb", argv[arg], 3) == 0) + { + usingNetbeans++; + gui.dofork = FALSE; /* don't fork() when starting GUI */ + netbeansArg = argv[arg]; + mch_memmove(&argv[arg], &argv[arg + 1], + (--*argc - arg) * sizeof(char *)); + } + else + #endif arg++; } } *************** *** 1428,1440 **** if (usingSunWorkShop) workshop_connect(app_context); #endif ! # ifdef FEAT_BEVAL gui_init_tooltip_font(); ! # endif ! # ifdef FEAT_MENU gui_init_menu_font(); ! # endif return OK; } --- 1449,1465 ---- if (usingSunWorkShop) workshop_connect(app_context); #endif + #ifdef FEAT_NETBEANS_INTG + if (usingNetbeans) + netbeans_Xt_connect(app_context); + #endif ! #ifdef FEAT_BEVAL gui_init_tooltip_font(); ! #endif ! #ifdef FEAT_MENU gui_init_menu_font(); ! #endif return OK; } *** ../vim61.365/src/main.c Thu Feb 20 21:54:31 2003 --- src/main.c Fri Feb 28 17:06:54 2003 *************** *** 147,152 **** --- 147,157 ---- int literal = FALSE; /* don't expand file names */ #endif + # ifdef NBDEBUG + nbdebug_wait(WT_ENV | WT_WAIT | WT_STOP, "SPRO_GVIM_WAIT", 20); + nbdebug_log_init("SPRO_GVIM_DEBUG", "SPRO_GVIM_DLEVEL"); + # endif + /* * Do any system-specific initialisations. These can NOT use IObuff or * NameBuff. Thus emsg2() cannot be called! *************** *** 308,313 **** --- 313,321 ---- #ifdef FEAT_SUN_WORKSHOP findYourself(argv[0]); #endif + #ifdef FEAT_NETBEANS_INTG + netbeans_setRunDir(argv[0]); + #endif #if defined(FEAT_GUI) && !defined(MAC_OS_CLASSIC) gui_prepare(&argc, argv); /* Prepare for possibly starting GUI sometime */ TIME_MSG("GUI prepared"); *************** *** 1178,1183 **** --- 1186,1195 ---- * Set the default values for the options that use Rows and Columns. */ ui_get_shellsize(); /* inits Rows and Columns */ + #ifdef FEAT_NETBEANS_INTG + if (usingNetbeans) + Columns += 2; /* leave room for glyph gutter */ + #endif firstwin->w_height = Rows - p_ch; topframe->fr_height = Rows - p_ch; #ifdef FEAT_VERTSPLIT *************** *** 1893,1898 **** --- 1905,1916 ---- if (restart_edit != 0) stuffcharReadbuff(K_IGNORE); + #ifdef FEAT_NETBEANS_INTG + if (usingNetbeans) + /* Tell the client that it can start sending commands. */ + netbeans_startup_done(); + #endif + TIME_MSG("before starting main loop"); /* *************** *** 2135,2140 **** --- 2153,2161 ---- #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) iconv_end(); #endif + #ifdef FEAT_NETBEANS_INTG + netbeans_end(); + #endif mch_exit(exitval); } *** ../vim61.365/src/memline.c Wed Feb 26 21:05:18 2003 --- src/memline.c Tue Mar 4 22:18:16 2003 *************** *** 210,216 **** static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name)); #endif #ifdef FEAT_BYTEOFF ! static void ml_updatechunk __ARGS((buf_T *buf, long line, int len, int updtype)); #endif /* --- 210,216 ---- static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name)); #endif #ifdef FEAT_BYTEOFF ! static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype)); #endif /* *************** *** 1922,1928 **** } /* ! * append a line after lnum (may be 0 to insert a line in front of the file) * * newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum * will be set for recovery --- 1922,1930 ---- } /* ! * Append a line after lnum (may be 0 to insert a line in front of the file). ! * "line" does not need to be allocated, but can't be another line in a ! * buffer, unlocking may make it invalid. * * newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum * will be set for recovery *************** *** 2431,2437 **** #ifdef FEAT_BYTEOFF /* The line was inserted below 'lnum' */ ! ml_updatechunk(buf, lnum + 1, len, ML_CHNK_ADDLINE); #endif return OK; } --- 2433,2444 ---- #ifdef FEAT_BYTEOFF /* The line was inserted below 'lnum' */ ! ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE); ! #endif ! #ifdef FEAT_NETBEANS_INTG ! if (STRLEN(line) > 0) ! netbeans_inserted(buf, lnum+1, (colnr_T)0, 0, line, STRLEN(line)); ! netbeans_inserted(buf, lnum+1, (colnr_T)STRLEN(line), 0, (char_u *)"\n", 1); #endif return OK; } *************** *** 2460,2471 **** if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL) == FAIL) return FAIL; if (curbuf->b_ml.ml_line_lnum != lnum) /* other line buffered */ ml_flush_line(curbuf); /* flush it */ else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */ vim_free(curbuf->b_ml.ml_line_ptr); /* free it */ - if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */ - return FAIL; curbuf->b_ml.ml_line_ptr = line; curbuf->b_ml.ml_line_lnum = lnum; curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY; --- 2467,2482 ---- if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL) == FAIL) return FAIL; + if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */ + return FAIL; + #ifdef FEAT_NETBEANS_INTG + netbeans_removed(curbuf, lnum, 0, (long)STRLEN(ml_get(lnum))); + netbeans_inserted(curbuf, lnum, 0, 0, line, STRLEN(line)); + #endif if (curbuf->b_ml.ml_line_lnum != lnum) /* other line buffered */ ml_flush_line(curbuf); /* flush it */ else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */ vim_free(curbuf->b_ml.ml_line_ptr); /* free it */ curbuf->b_ml.ml_line_ptr = line; curbuf->b_ml.ml_line_lnum = lnum; curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY; *************** *** 2506,2512 **** int stack_idx; int text_start; int line_start; ! int line_size; int i; if (lnum < 1 || lnum > buf->b_ml.ml_line_count) --- 2517,2523 ---- int stack_idx; int text_start; int line_start; ! long line_size; int i; if (lnum < 1 || lnum > buf->b_ml.ml_line_count) *************** *** 2520,2526 **** */ if (buf->b_ml.ml_line_count == 1) /* file becomes empty */ { ! if (message) { set_keep_msg((char_u *)_(no_lines_msg)); keep_msg_attr = 0; --- 2531,2541 ---- */ if (buf->b_ml.ml_line_count == 1) /* file becomes empty */ { ! if (message ! #ifdef FEAT_NETBEANS_INTG ! && !netbeansSuppressNoLines ! #endif ! ) { set_keep_msg((char_u *)_(no_lines_msg)); keep_msg_attr = 0; *************** *** 2558,2563 **** --- 2573,2582 ---- else line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start; + #ifdef FEAT_NETBEANS_INTG + netbeans_removed(buf, lnum, 0, line_size); + #endif + /* * special case: If there is only one line in the data block it becomes empty. * Then we have to remove the entry, pointing to this data block, from the *************** *** 2851,2857 **** buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS); #ifdef FEAT_BYTEOFF /* The else case is already covered by the insert and delete */ ! ml_updatechunk(buf, lnum, extra, ML_CHNK_UPDLINE); #endif } else --- 2870,2876 ---- buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS); #ifdef FEAT_BYTEOFF /* The else case is already covered by the insert and delete */ ! ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE); #endif } else *************** *** 3965,3971 **** ml_updatechunk(buf, line, len, updtype) buf_T *buf; linenr_T line; ! int len; int updtype; { static buf_T *ml_upd_lastbuf = NULL; --- 3984,3990 ---- ml_updatechunk(buf, line, len, updtype) buf_T *buf; linenr_T line; ! long len; int updtype; { static buf_T *ml_upd_lastbuf = NULL; *************** *** 3981,3987 **** bhdr_T *hp; DATA_BL *dp; ! if (buf->b_ml.ml_usedchunks == -1 || !len) return; if (buf->b_ml.ml_chunksize == NULL) { --- 4000,4006 ---- bhdr_T *hp; DATA_BL *dp; ! if (buf->b_ml.ml_usedchunks == -1 || len == 0) return; if (buf->b_ml.ml_chunksize == NULL) { *** ../vim61.365/src/misc1.c Mon Feb 24 11:29:15 2003 --- src/misc1.c Fri Mar 7 22:30:02 2003 *************** *** 1916,1925 **** * existing line. Otherwise a new line has to be allocated */ was_alloced = ml_line_alloced(); /* check if oldp was allocated */ if (was_alloced) newp = oldp; /* use same allocated memory */ else ! { /* need to allocated a new line */ newp = alloc((unsigned)(oldlen + 1 - count)); if (newp == NULL) return FAIL; --- 1916,1930 ---- * existing line. Otherwise a new line has to be allocated */ was_alloced = ml_line_alloced(); /* check if oldp was allocated */ + #ifdef FEAT_NETBEANS_INTG + if (was_alloced) + netbeans_removed(curbuf, lnum, col, count); + /* else is handled by ml_replace() */ + #endif if (was_alloced) newp = oldp; /* use same allocated memory */ else ! { /* need to allocate a new line */ newp = alloc((unsigned)(oldlen + 1 - count)); if (newp == NULL) return FAIL; *************** *** 2412,2417 **** --- 2417,2425 ---- } ++buf->b_changedtick; ++global_changedtick; + #ifdef FEAT_NETBEANS_INTG + netbeans_unmodified(buf); + #endif } #if defined(FEAT_WINDOWS) || defined(PROTO) *************** *** 3797,3803 **** ++y; --len; } ! if (len <= 0) return 0; return (*x - *y); } --- 3805,3811 ---- ++y; --len; } ! if (len == 0) return 0; return (*x - *y); } *** ../vim61.365/src/misc2.c Wed Jan 29 22:08:43 2003 --- src/misc2.c Mon Mar 3 12:33:55 2003 *************** *** 2634,2640 **** #if defined(FEAT_SESSION) || defined(MSWIN) \ || (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) \ ! || defined(FEAT_SUN_WORKSHOP) || defined(PROTO) /* * Change to a file's directory. * Caller must call shorten_fnames()! --- 2638,2645 ---- #if defined(FEAT_SESSION) || defined(MSWIN) \ || (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) \ ! || defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \ ! || defined(PROTO) /* * Change to a file's directory. * Caller must call shorten_fnames()! *** ../vim61.365/src/move.c Thu Jan 9 22:01:16 2003 --- src/move.c Thu Feb 13 20:08:09 2003 *************** *** 893,899 **** + wp->w_p_fdc #endif #ifdef FEAT_SIGNS ! + (wp->w_buffer->b_signlist != NULL ? 2 : 0) #endif ); } --- 893,904 ---- + wp->w_p_fdc #endif #ifdef FEAT_SIGNS ! + ( ! # ifdef FEAT_NETBEANS_INTG ! /* always show glyph gutter in netbeans */ ! usingNetbeans || ! # endif ! wp->w_buffer->b_signlist != NULL ? 2 : 0) #endif ); } *** ../vim61.365/src/nbdebug.c Sat Mar 8 17:24:27 2003 --- src/nbdebug.c Thu Feb 13 16:41:13 2003 *************** *** 0 **** --- 1,175 ---- + /* vi:set ts=8 sts=8 sw=8: + * + * VIM - Vi IMproved by Bram Moolenaar + * Visual Workshop integration by Gordon Prieur + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + + /* + * NetBeans Debugging Tools. What are these tools and why are they important? + * There are two main tools here. The first tool is a tool for delaying or + * stopping gvim during startup. The second tool is a protocol log tool. + * + * The startup delay tool is called nbdebug_wait(). This is very important for + * debugging startup problems because gvim will be started automatically from + * netbeans and cannot be run directly from a debugger. The only way to debug + * a gvim started by netbeans is by attaching a debugger to it. Without this + * tool all starup code will have completed before you can get the pid and + * attach. + * + * The second tool is a log tool. + * + * This code must have NBDEBUG defined for it to be compiled into vim/gvim. + */ + + #ifdef NBDEBUG + + #include + + #include "vim.h" + + FILE *nb_debug = NULL; + u_int nb_dlevel = 0; /* nb_debug verbosity level */ + + void nbdb(char *, ...); + void nbtrace(char *, ...); + + static int lookup(char *); + static int errorHandler(Display *, XErrorEvent *); + + + /* + * nbdebug_wait - This function can be used to delay or stop execution of vim. + * Its normally used to delay startup while attaching a + * debugger to a running process. Since workshop starts gvim + * from a background process this is the only way to debug + * startup problems. + */ + + void nbdebug_wait( + u_int wait_flags, /* tells what to do */ + char *wait_var, /* wait environment variable */ + u_int wait_secs) /* how many seconds to wait */ + { + + init_homedir(); /* not inited yet */ + #ifdef USE_WDDUMP + WDDump(0, 0, 0); + #endif + + /* for debugging purposes only */ + if (wait_flags & WT_ENV && wait_var && getenv(wait_var) != NULL) { + sleep(atoi(getenv(wait_var))); + } else if (wait_flags & WT_WAIT && lookup("~/.gvimwait")) { + sleep(wait_secs > 0 && wait_secs < 120 ? wait_secs : 20); + } else if (wait_flags & WT_STOP && lookup("~/.gvimstop")) { + int w = 1; + while (w) { + ; + } + } + } /* end nbdebug_wait */ + + + void + nbdebug_log_init( + char *log_var, /* env var with log file */ + char *level_var) /* env var with nb_debug level */ + { + char *file; /* possible nb_debug output file */ + char *cp; /* nb_dlevel pointer */ + + if (log_var && (file = getenv(log_var)) != NULL) { + char buf[BUFSIZ]; + + sprintf(buf, "date > %s", file); + system(buf); + nb_debug = fopen(file, "a"); + if (level_var && (cp = getenv(level_var)) != NULL) { + nb_dlevel = strtoul(cp, NULL, 0); + } else { + nb_dlevel = NB_TRACE; /* default level */ + } + /* XSetErrorHandler(errorHandler); */ + } + + } /* end nbdebug_log_init */ + + + + + void + nbtrace( + char *fmt, + ...) + { + va_list ap; + + if (nb_debug!= NULL && (nb_dlevel & (NB_TRACE | NB_TRACE_VERBOSE))) { + va_start(ap, fmt); + vfprintf(nb_debug, fmt, ap); + va_end(ap); + fflush(nb_debug); + } + + } /* end nbtrace */ + + + void + nbdbg( + char *fmt, + ...) + { + va_list ap; + + if (nb_debug != NULL) { + va_start(ap, fmt); + vfprintf(nb_debug, fmt, ap); + va_end(ap); + fflush(nb_debug); + } + + } /* end nbdbg */ + + + static int + lookup( + char *file) + { + char buf[BUFSIZ]; + + expand_env((char_u *) file, (char_u *) buf, BUFSIZ); + return (access(buf, F_OK) == 0); + + } /* end lookup */ + + static int + errorHandler( + Display *dpy, + XErrorEvent *err) + { + char msg[256]; + char buf[256]; + + XGetErrorText(dpy, err->error_code, msg, sizeof(msg)); + nbdbg("\n\nNBDEBUG Vim: X Error of failed request: %s\n", msg); + + sprintf(buf, "%d", err->request_code); + XGetErrorDatabaseText(dpy, + "XRequest", buf, "Unknown", msg, sizeof(msg)); + nbdbg("\tMajor opcode of failed request: %d (%s)\n", + err->request_code, msg); + if (err->request_code > 128) { + nbdbg("\tMinor opcode of failed request: %d\n", + err->minor_code); + } + + return 0; + } + + + + #endif /* NBDEBUG */ *** ../vim61.365/src/nbdebug.h Sat Mar 8 17:24:27 2003 --- src/nbdebug.h Thu Feb 13 16:41:13 2003 *************** *** 0 **** --- 1,79 ---- + /* vi:set ts=8 sts=8 sw=8: + * + * VIM - Vi IMproved by Bram Moolenaar + * Visual Workshop integration by Gordon Prieur + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + */ + + + #ifndef NBDEBUG_H + #define NBDEBUG_H + + #ifdef NBDEBUG + + #ifndef ASSERT + #define ASSERT(c) \ + if (!(c)) { \ + fprintf(stderr, "Assertion failed: line %d, file %s\n", \ + __LINE__, __FILE__); \ + fflush(stderr); \ + abort(); \ + } + #endif + + #define nbdebug(a) nbdbg##a + + #define NB_TRACE 0x00000001 + #define NB_TRACE_VERBOSE 0x00000002 + #define NB_TRACE_COLONCMD 0x00000004 + #define NB_DEBUG_ALL 0xffffffff + + #define NBDLEVEL(flags) (nb_debug != NULL && (nb_dlevel & (flags))) + + #define NBDEBUG_TRACE 1 + //#define NBDEBUG_SENSE 2 + + typedef enum { + WT_ENV = 1, /* look for env var if set */ + WT_WAIT, /* look for ~/.gvimwait if set */ + WT_STOP /* look for ~/.gvimstop if set */ + } WtWait; + + + void nbdbg(char *, ...); + void nbtrace(char *, ...); + + + extern FILE *nb_debug; + extern u_int nb_dlevel; /* nb_debug verbosity level */ + + # else /* not NBDEBUG */ + + #ifndef ASSERT + # define ASSERT(c) + #endif + + /* + * The following 2 stubs are needed because a macro cannot be used because of + * the variable number of arguments. + */ + + void + nbdbg( + char *fmt, + ...) + { + } + + + void + nbtrace( + char *fmt, + ...) + { + } + + #endif /* NBDEBUG */ + #endif /* NBDEBUG_H */ *** ../vim61.365/src/netbeans.c Sat Mar 8 17:24:27 2003 --- src/netbeans.c Sat Mar 8 17:10:36 2003 *************** *** 0 **** --- 1,2914 ---- + /* vi:set ts=8 sts=4 sw=4: + * + * VIM - Vi IMproved by Bram Moolenaar + * Netbeans integration by David Weatherford + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + */ + + /* + * Implements client side of org.netbeans.modules.emacs editor + * integration protocol. Be careful! The protocol uses offsets + * which are *between* characters, whereas vim uses line number + * and column number which are *on* characters. + * See ":help netbeans-protocol" for explanation. + */ + + #include "vim.h" + + /* Note: when making changes here also adjust configure.in. */ + #include + #include + #include + #include + #include + #ifdef HAVE_LIBGEN_H + # include + #endif + + #include "version.h" + + #define INET_SOCKETS + + #define GUARDED 10000 /* typenr for "guarded" annotation */ + #define GUARDEDOFFSET 1000000 /* base for "guarded" sign id's */ + + /* The first implementation (working only with Netbeans) returned "1.1". The + * protocol implemented here also supports A-A-P. */ + static char *ExtEdProtocolVersion = "2.1"; + + static long pos2off __ARGS((buf_T *, pos_T *)); + static pos_T *off2pos __ARGS((buf_T *, long)); + static pos_T *get_off_or_lnum __ARGS((buf_T *buf, char_u **argp)); + static long get_buf_size __ARGS((buf_T *)); + + static void netbeans_connect __ARGS((void)); + + static void nb_init_graphics __ARGS((void)); + static void coloncmd __ARGS((char *cmd, ...)); + #ifdef FEAT_GUI_MOTIF + static void messageFromNetbeans __ARGS((XtPointer, int *, XtInputId *)); + #endif + #ifdef FEAT_GUI_GTK + static void messageFromNetbeans __ARGS((gpointer, gint, GdkInputCondition)); + #endif + static void nb_parse_cmd __ARGS((char_u *)); + static int nb_do_cmd __ARGS((int, char_u *, int, int, char_u *)); + static void nb_send __ARGS((char *buf, char *fun)); + static void warn __ARGS((char *fmt, ...)); + + static int sd = -1; /* socket fd for Netbeans connection */ + #ifdef FEAT_GUI_MOTIF + static XtInputId inputHandler; /* Cookie for input */ + #endif + #ifdef FEAT_GUI_GTK + static gint inputHandler; /* Cookie for input */ + #endif + static int cmdno; /* current command number for reply */ + static int needGraphicsInit = 1; + static int haveConnection = FALSE; /* socket is connected and + initialization is done */ + static int oldFire = 1; + static int exit_delay = 2; /* exit delay in seconds */ + + #if defined(FEAT_BEVAL) + extern Widget textArea; + BalloonEval *balloonEval = NULL; + #endif + + /* + * Include the debugging code if wanted. + */ + #ifdef NBDEBUG + # include "nbdebug.c" + #endif + + /* Connect back to Netbeans process */ + #if defined(FEAT_GUI_MOTIF) || defined(PROTO) + void + netbeans_Xt_connect(void *context) + { + netbeans_connect(); + if (sd > 0) + { + /* tell notifier we are interested in being called + * when there is input on the editor connection socket + */ + inputHandler = XtAppAddInput((XtAppContext)context, sd, + (XtPointer)(XtInputReadMask + XtInputExceptMask), + messageFromNetbeans, NULL); + } + } + + static void + netbeans_disconnect(void) + { + if (inputHandler != (XtInputId)NULL) + { + XtRemoveInput(inputHandler); + inputHandler = (XtInputId)NULL; + } + sd = -1; + haveConnection = FALSE; + } + #endif /* FEAT_MOTIF_GUI */ + + #if defined(FEAT_GUI_GTK) || defined(PROTO) + void + netbeans_gtk_connect(void) + { + netbeans_connect(); + if (sd > 0) + { + /* + * Tell gdk we are interested in being called when there + * is input on the editor connection socket + */ + inputHandler = gdk_input_add(sd, (GdkInputCondition) + ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION), + messageFromNetbeans, NULL); + } + } + + static void + netbeans_disconnect(void) + { + if (inputHandler != 0) + { + gdk_input_remove(inputHandler); + inputHandler = 0; + } + sd = -1; + haveConnection = FALSE; + } + #endif /* FEAT_GUI_GTK */ + + static void + netbeans_connect(void) + { + #ifdef INET_SOCKETS + struct sockaddr_in server; + struct hostent * host; + int port; + #else + struct sockaddr_un server; + #endif + char buf[32]; + char * hostname; + char * address; + char * password; + + /* netbeansArg is -nb or -nb::: */ + if (netbeansArg[3] == ':') + netbeansArg += 4; + else + netbeansArg = NULL; + + hostname = netbeansArg; + if (hostname == NULL || *hostname == '\0') + hostname = getenv("__NETBEANS_HOST"); + if (hostname == NULL || *hostname == '\0') + hostname = "localhost"; /* default */ + + address = strchr(hostname, ':'); + if (address != NULL) + *address++ = '\0'; + else + address = getenv("__NETBEANS_SOCKET"); + if (address == NULL || *address == '\0') + address = "3219"; /* default */ + + password = strchr(address, ':'); + if (password != NULL) + *password++ = '\0'; + else + password = getenv("__NETBEANS_VIM_PASSWORD"); + if (password == NULL || *password == '\0') + password = "changeme"; /* default */ + + #ifdef INET_SOCKETS + port = atoi(address); + + if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + perror("socket() in netbeans_connect()"); + return; + } + + /* Get the server internet address and put into addr structure */ + /* fill in the socket address structure and connect to server */ + memset((char *)&server, '\0', sizeof(server)); + server.sin_family = AF_INET; + server.sin_port = htons(port); + if ((host = gethostbyname(hostname)) == NULL) + { + if (access(hostname, R_OK) >= 0) + { + /* DEBUG: input file */ + sd = open(hostname, O_RDONLY); + return; + } + perror("gethostbyname() in netbeans_connect()"); + sd = -1; + return; + } + memcpy((char *)&server.sin_addr, host->h_addr, host->h_length); + #else + if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + { + perror("socket()"); + return; + } + + server.sun_family = AF_UNIX; + strcpy(server.sun_path, address); + #endif + /* Connect to server */ + if (connect(sd, (struct sockaddr *)&server, sizeof(server))) + { + nbdebug(("netbeans_connect: Connect failed with errno %d\n", errno)); + if (errno == ECONNREFUSED) + { + close(sd); + #ifdef INET_SOCKETS + if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + perror("socket()#2 in netbeans_connect()"); + return; + } + #else + if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + { + perror("socket()#2 in netbeans_connect()"); + return; + } + #endif + if (connect(sd, (struct sockaddr *)&server, sizeof(server))) + { + int retries = 36; + int success = FALSE; + while (retries-- + && ((errno == ECONNREFUSED) || (errno == EINTR))) + { + nbdebug(("retrying...\n")); + sleep(5); + if (connect(sd, (struct sockaddr *)&server, + sizeof(server)) == 0) + { + success = TRUE; + break; + } + } + if (!success) + { + /* Get here when the server can't be found. */ + perror(_("Cannot connect to Netbeans #2")); + getout(1); + } + } + + } + else + { + perror(_("Cannot connect to Netbeans")); + getout(1); + } + } + + sprintf(buf, "AUTH %s\n", password); + nb_send(buf, "netbeans_connect"); + + sprintf(buf, "0:version=0 \"%s\"\n", ExtEdProtocolVersion); + nb_send(buf, "externaleditor_version"); + + nbdebug(("netbeans_connect: Connnection succeeded\n")); + + /* nb_init_graphics(); delay until needed */ + + haveConnection = TRUE; + + return; + } + + + struct keyqueue + { + int key; + struct keyqueue *next; + struct keyqueue *prev; + }; + + typedef struct keyqueue keyQ_T; + + static keyQ_T keyHead; /* dummy node, header for circular queue */ + + + /* + * Queue up key commands sent from netbeans. + */ + static void + postpone_keycommand(int key) + { + keyQ_T *node; + + node = (keyQ_T *)alloc(sizeof(keyQ_T)); + + if (keyHead.next == NULL) /* initialize circular queue */ + { + keyHead.next = &keyHead; + keyHead.prev = &keyHead; + } + + /* insert node at tail of queue */ + node->next = &keyHead; + node->prev = keyHead.prev; + keyHead.prev->next = node; + keyHead.prev = node; + + node->key = key; + } + + /* + * Handle any queued-up NetBeans keycommands to be send. + */ + static void + handle_key_queue(void) + { + while (keyHead.next && keyHead.next != &keyHead) + { + /* first, unlink the node */ + keyQ_T *node = keyHead.next; + keyHead.next = node->next; + node->next->prev = node->prev; + + /* now, send the keycommand */ + netbeans_keycommand(node->key); + + /* Finally, dispose of the node */ + vim_free(node); + } + } + + + struct cmdqueue + { + char_u *buffer; + struct cmdqueue *next; + struct cmdqueue *prev; + }; + + typedef struct cmdqueue queue_T; + + static queue_T head; /* dummy node, header for circular queue */ + + + /* + * Put the buffer on the work queue; possibly save it to a file as well. + */ + static void + save(char_u *buf, int len) + { + queue_T *node; + + node = (queue_T *)alloc(sizeof(queue_T)); + if (node == NULL) + return; /* out of memory */ + node->buffer = alloc(len + 1); + if (node->buffer == NULL) + { + vim_free(node); + return; /* out of memory */ + } + mch_memmove(node->buffer, buf, (size_t)len); + node->buffer[len] = NUL; + + if (head.next == NULL) /* initialize circular queue */ + { + head.next = &head; + head.prev = &head; + } + + /* insert node at tail of queue */ + node->next = &head; + node->prev = head.prev; + head.prev->next = node; + head.prev = node; + + #ifdef NBDEBUG + { + static int outfd = -2; + + /* possibly write buffer out to a file */ + if (outfd == -3) + return; + + if (outfd == -2) + { + char *file = getenv("__NETBEANS_SAVE"); + if (file == NULL) + outfd = -3; + else + outfd = open(file, O_WRONLY|O_CREAT|O_TRUNC, 0666); + } + + if (outfd >= 0) + write(outfd, buf, len); + } + #endif + } + + + /* + * While there's still a command in the work queue, parse and execute it. + */ + static void + nb_parse_messages(void) + { + char_u *p; + queue_T *node; + + while (head.next != &head) + { + node = head.next; + + /* Locate the first line in the first buffer. */ + p = vim_strchr(node->buffer, '\n'); + if (p == NULL) + { + /* Command isn't complete. If there is no following buffer, + * return (wait for more). If there is another buffer following, + * prepend the text to that buffer and delete this one. */ + if (node->next == &head) + return; + p = alloc(STRLEN(node->buffer) + STRLEN(node->next->buffer) + 1); + if (p == NULL) + return; /* out of memory */ + STRCPY(p, node->buffer); + STRCAT(p, node->next->buffer); + vim_free(node->next->buffer); + node->next->buffer = p; + + /* dispose of the node and buffer */ + head.next = node->next; + node->next->prev = node->prev; + vim_free(node->buffer); + vim_free(node); + } + else + { + /* There is a complete command at the start of the buffer. + * Terminate it with a NUL. When no more text is following unlink + * the buffer. Do this before executing, because new buffers can + * be added while busy handling the command. */ + *p++ = NUL; + if (*p == NUL) + { + head.next = node->next; + node->next->prev = node->prev; + } + + /* now, parse and execute the commands */ + nb_parse_cmd(node->buffer); + + if (*p == NUL) + { + /* buffer finished, dispose of the node and buffer */ + vim_free(node->buffer); + vim_free(node); + } + else + /* more follows, move to the start */ + mch_memmove(node->buffer, p, STRLEN(p) + 1); + } + } + } + + /* Buffer size for reading incoming messages. */ + #define MAXMSGSIZE 4096 + + /* + * Read and process a command from netbeans. + */ + /*ARGSUSED*/ + #ifdef FEAT_GUI_MOTIF + static void + messageFromNetbeans(XtPointer clientData, int *unused1, XtInputId *unused2) + #endif + #ifdef FEAT_GUI_GTK + static void + messageFromNetbeans(gpointer clientData, gint unused1, + GdkInputCondition unused2) + #endif + { + static char_u *buf = NULL; + int len; + int readlen = 0; + static int level = 0; + + if (sd < 0) + { + nbdebug(("messageFromNetbeans() called without a socket\n")); + return; + } + + ++level; /* recursion guard; this will be called from the X event loop */ + + /* Allocate a buffer to read into. */ + if (buf == NULL) + { + buf = alloc(MAXMSGSIZE); + if (buf == NULL) + return; /* out of memory! */ + } + + /* Keep on reading for as long as there is something to read. */ + for (;;) + { + len = read(sd, buf, MAXMSGSIZE); + if (len <= 0) + break; /* error or nothing more to read */ + + /* Store the read message in the queue. */ + save(buf, len); + readlen += len; + + if (len < MAXMSGSIZE) + break; /* did read everything that's available */ + } + + if (readlen <= 0) + { + /* read error or didn't read anything */ + netbeans_disconnect(); + nbdebug(("messageFromNetbeans: Error in read() from socket\n")); + if (len < 0) + perror(_("read from Netbeans socket")); + return; /* don't try to parse it */; + } + + /* Parse the messages, but avoid recursion. */ + if (level == 1) + nb_parse_messages(); + + --level; + } + + /* + * Issue a warning. This used to go to stderr but that doesn't show up when + * started from a GUI. + */ + static void + warn(char *fmt, ...) + { + va_list ap; + char buf[1000]; + + va_start(ap, fmt); + vsnprintf(buf, 1000, fmt, ap); + va_end(ap); + EMSG(buf); + } + + /* + * Issue a warning to stderr and possibly abort. + */ + #if 0 /* we should never abort, changed files could be lost! */ + static void die __ARGS((char *fmt, ...)); + + static void + die(char *fmt, ...) + { + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + /* exit(1); */ + if (getenv("__NETBEANS_INTG_ABORT")) + abort(); + } + #else + # define die warn + #endif + + /* + * Handle one NUL terminated command. + * + * format of a command from netbeans: + * + * 6:setTitle!84 "a.c" + * + * bufno + * colon + * cmd + * ! + * cmdno + * args + * + * for function calls, the ! is replaced by a / + */ + static void + nb_parse_cmd(char_u *cmd) + { + char_u *verb; + char_u *q; + int bufno; + int iscmd = 0; + int isfunc = 0; + + if (STRCMP(cmd, "DISCONNECT") == 0) + { + /* We assume the server knows that we can safely exit! */ + if (sd >= 0) + close(sd); + /* Disconnect before exiting, Motif hangs in a Select error + * message otherwise. */ + netbeans_disconnect(); + getout(0); + /* NOTREACHED */ + } + + bufno = strtol((char *)cmd, (char **)&verb, 10); + + if (*verb != ':') + { + warn("missing colon: %s", cmd); + return; + } + ++verb; /* skip colon */ + + for (q = verb; *q; q++) + { + if (*q == '!') + { + *q++ = NUL; + iscmd = 1; + break; + } + else if (*q == '/') + { + *q++ = NUL; + isfunc = 1; + break; + } + } + + if (!iscmd && !isfunc) + { + warn("missing ! or / in: %s", cmd); + return; + } + + cmdno = strtol((char *)q, (char **)&q, 10); + + if (nb_do_cmd(bufno, verb, isfunc, cmdno, q) == FAIL) + die("bad return from nb_do_cmd"); + } + + struct nbbuf_struct + { + buf_T *bufp; + #if 0 /* never used */ + unsigned int netbeansOwns:1; + unsigned int fireCaret:1; + #endif + unsigned int fireChanges:1; + unsigned int initDone:1; + unsigned int modified:1; + #if 0 /* never used */ + char *internalname; + #endif + char *displayname; + char_u *partial_line; + int *signmap; + ushort signmaplen; + ushort signmapused; + }; + + typedef struct nbbuf_struct nbbuf_T; + + static nbbuf_T *buf_list = 0; + int buf_list_size = 0; + int buf_list_used = -1; /* last index in use */ + + static char **globalsignmap; + static int globalsignmaplen; + static int globalsignmapused; + + static int mapsigntype __ARGS((nbbuf_T *, int localsigntype)); + static void addsigntype __ARGS((nbbuf_T *, int localsigntype, char_u *typeName, + char_u *tooltip, char_u *glyphfile, + int usefg, int fg, int usebg, int bg)); + + static int curPCtype = -1; + + /* + * Get the Netbeans buffer number for the specified buffer. + */ + static int + nb_getbufno(buf_T *bufp) + { + int i; + + for (i = 0; i <= buf_list_used; i++) + { + if (buf_list[i].bufp == bufp) + return i; + } + + return -1; + } + + /* + * Given a Netbeans buffer number, return the netbeans buffer. + * Returns NULL for a negative number. + */ + static nbbuf_T * + nb_get_buf(int bufno) + { + /* find or create a buffer with the given number */ + int incr; + + if (bufno < 0) + return NULL; + + if (!buf_list) + { + /* initialize */ + buf_list = (nbbuf_T *)alloc_clear(100 * sizeof(nbbuf_T)); + buf_list_size = 100; + } + if (bufno > buf_list_used) /* new */ + { + if (bufno >= buf_list_size) /* grow list */ + { + incr = 100; + buf_list_size += incr; + buf_list = (nbbuf_T *)vim_realloc( + buf_list, buf_list_size * sizeof(nbbuf_T)); + memset(buf_list + buf_list_size - incr, 0, incr * sizeof(nbbuf_T)); + } + + while (buf_list_used < bufno) + { + /* Default is to fire text changes. */ + buf_list[buf_list_used].fireChanges = 1; + ++buf_list_used; + } + } + + return buf_list + bufno; + } + + /* + * End the netbeans session. + */ + void + netbeans_end(void) + { + int i; + static char buf[128]; + + if (!haveConnection) + return; + + for (i = 0; i <= buf_list_used; i++) + { + if (!buf_list[i].bufp) + continue; + if (netbeansForcedQuit) + { + /* mark as unmodified so NetBeans won't put up dialog on "killed" */ + sprintf(buf, "%d:unmodified=%d\n", i, cmdno); + nbdebug(("EVT: %s", buf)); + nb_send(buf, "netbeans_end"); + } + sprintf(buf, "%d:killed=%d\n", i, cmdno); + nbdebug(("EVT: %s", buf)); + /* nb_send(buf, "netbeans_end"); avoid "write failed" messages */ + if (sd >= 0) + write(sd, buf, STRLEN(buf)); /* ignore errors */ + } + + /* Give NetBeans a chance to write some clean-up cmds to the socket before + * we close the connection. Other clients may set the delay to zero. */ + if (exit_delay > 0) + sleep(exit_delay); + } + + /* + * Send a message to netbeans. + */ + static void + nb_send(char *buf, char *fun) + { + if (sd < 0) + warn("%s(): write while not connected", fun); + else if (write(sd, buf, STRLEN(buf)) != STRLEN(buf)) + warn("%s(): write failed", fun); + } + + /* + * Some input received from netbeans requires a response. This function + * handles a response with no information (except the command number). + */ + static void + nb_reply_nil(int cmdno) + { + static char reply[32]; + + if (!haveConnection) + return; + + sprintf(reply, "%d\n", cmdno); + + nbdebug((" REPLY: %s", reply)); + + nb_send(reply, "nb_reply_nil"); + } + + + /* + * Send a response with text. + */ + static void + nb_reply_text(int cmdno, char_u *result) + { + char_u *reply; + + if (!haveConnection) + return; + + reply = alloc(STRLEN(result) + 32); + sprintf((char *)reply, "%d %s\n", cmdno, (char *)result); + + nbdebug((" REPLY: %s", reply)); + nb_send((char *)reply, "nb_reply_text"); + + vim_free(reply); + } + + + /* + * Send a response with an integer result code. + */ + static void + nb_reply_int(int cmdno, long result) + { + static char reply[32]; + + if (!haveConnection) + return; + + sprintf(reply, "%d %ld\n", cmdno, result); + + nbdebug(("REPLY: %s", reply)); + + nb_send(reply, "nb_reply_int"); + } + + + /* + * Encode newline, ret, backslash, double quote for transmission to NetBeans. + */ + static char_u * + nb_quote(char_u *txt) + { + char_u *buf = alloc(2 * STRLEN(txt) + 1); + char_u *p = txt; + char_u *q = buf; + + for (; *p; p++) + { + switch (*p) + { + case '\"': + case '\\': + *q++ = '\\'; *q++ = *p; break; + /* case '\t': */ + /* *q++ = '\\'; *q++ = 't'; break; */ + case '\n': + *q++ = '\\'; *q++ = 'n'; break; + case '\r': + *q++ = '\\'; *q++ = 'r'; break; + default: + *q++ = *p; + break; + } + } + *q++ = '\0'; + + return buf; + } + + + /* + * Remove top level double quotes; convert backslashed chars. + * Returns an allocated string (NULL for failure). + * If "endp" is not NULL it is set to the character after the terminating + * quote. + */ + static char * + nb_unquote(char_u *p, char_u **endp) + { + char *result = 0; + char *q; + int done = 0; + + /* result is never longer than input */ + result = (char *)alloc_clear(STRLEN(p) + 1); + if (result == NULL) + return NULL; + + if (*p++ != '"') + { + nbdebug(("nb_unquote called with string that doesn't start with a quote!: %s", p)); + result[0] = NUL; + return result; + } + + for (q = result; !done && *p != NUL;) + { + switch (*p) + { + case '"': + /* + * Unbackslashed dquote marks the end, if first char was dquote. + */ + done = 1; + break; + + case '\\': + ++p; + switch (*p) + { + case '\\': *q++ = '\\'; break; + case 'n': *q++ = '\n'; break; + case 't': *q++ = '\t'; break; + case 'r': *q++ = '\r'; break; + case '"': *q++ = '"'; break; + } + ++p; + break; + + default: + *q++ = *p++; + } + } + + if (endp != NULL) + *endp = p; + + return result; + } + + #define SKIP_STOP 2 + #define streq(a,b) (strcmp(a,b) == 0) + static int needupdate = 0; + static int inAtomic = 0; + + /* + * Do the actual processing of a single netbeans command or function. + * The differance between a command and function is that a function + * gets a response (its required) but a command does not. + * For arguments see comment for nb_parse_cmd(). + */ + static int + nb_do_cmd( + int bufno, + char_u *cmd, + int func, + int cmdno, + char_u *args) /* points to space before arguments or NUL */ + { + int doupdate = 0; + long off = 0; + nbbuf_T *buf = nb_get_buf(bufno); + static int skip = 0; + int retval = OK; + + nbdebug(("%s %d: (%d) %s %s\n", (func) ? "FUN" : "CMD", cmdno, bufno, cmd, + STRCMP(cmd, "insert") == 0 ? "" : (char *)args)); + + if (func) + { + /* =====================================================================*/ + if (streq((char *)cmd, "getLength")) + { + long len = 0; + + if (buf == NULL || buf->bufp == NULL) + { + die("null bufp in getLength"); + retval = FAIL; + } + else + { + len = get_buf_size(buf->bufp); + /* adjust for a partial last line */ + if (buf->partial_line != NULL) + { + nbdebug((" Adjusting buffer len for partial last line: %d\n", + STRLEN(buf->partial_line))); + len += STRLEN(buf->partial_line); + } + } + nb_reply_int(cmdno, len); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "getText")) + { + long len; + linenr_T nlines; + char_u *text = NULL; + linenr_T lno = 1; + char_u *p; + char_u *line; + + if (buf == NULL || buf->bufp == NULL) + { + die("null bufp in getText"); + retval = FAIL; + } + else + { + len = get_buf_size(buf->bufp); + nlines = buf->bufp->b_ml.ml_line_count; + text = alloc((unsigned)((len > 0) + ? ((len + nlines) * 2) : 4)); + if (text == NULL) + retval = FAIL; + else + { + p = text; + *p++ = '\"'; + for (; lno <= nlines ; lno++) + { + line = nb_quote(ml_get_buf(buf->bufp, lno, FALSE)); + if (line != NULL) + { + STRCPY(p, line); + p += STRLEN(line); + *p++ = '\\'; + *p++ = 'n'; + } + vim_free(line); + } + *p++ = '\"'; + *p = '\0'; + } + } + if (text == NULL) + nb_reply_text(cmdno, (char_u *)""); + else + { + nb_reply_text(cmdno, text); + vim_free(text); + } + /* =====================================================================*/ + } + else if (streq((char *)cmd, "remove")) + { + long count; + pos_T first, last; + pos_T *pos; + int oldFire = netbeansFireChanges; + int oldSuppress = netbeansSuppressNoLines; + int wasChanged; + + if (skip >= SKIP_STOP) + { + nbdebug((" Skipping %s command\n", (char *) cmd)); + nb_reply_nil(cmdno); + return OK; + } + + if (buf == NULL || buf->bufp == NULL) + { + die("null bufp in remove"); + retval = FAIL; + } + else + { + netbeansFireChanges = FALSE; + netbeansSuppressNoLines = TRUE; + + if (curbuf != buf->bufp) + set_curbuf(buf->bufp, DOBUF_GOTO); + wasChanged = buf->bufp->b_changed; + off = strtol((char *)args, (char **)&args, 10); + count = strtol((char *)args, (char **)&args, 10); + /* delete "count" chars, starting at "off" */ + pos = off2pos(buf->bufp, off); + if (!pos) + { + nb_reply_text(cmdno, (char_u *)"!bad position"); + netbeansFireChanges = oldFire; + netbeansSuppressNoLines = oldSuppress; + return FAIL; + } + first = *pos; + nbdebug((" FIRST POS: line %d, col %d\n", first.lnum, first.col)); + pos = off2pos(buf->bufp, off+count-1); + if (!pos) + { + nb_reply_text(cmdno, (char_u *)"!bad count"); + netbeansFireChanges = oldFire; + netbeansSuppressNoLines = oldSuppress; + return FAIL; + } + last = *pos; + nbdebug((" LAST POS: line %d, col %d\n", last.lnum, last.col)); + curwin->w_cursor = first; + doupdate = 1; + + /* keep part of first line */ + if (first.lnum == last.lnum && first.col != last.col) + { + /* deletion is within one line */ + char_u *p = ml_get(first.lnum); + mch_memmove(p + first.col, p + last.col + 1, STRLEN(p + last.col) + 1); + nbdebug((" NEW LINE %d: %s\n", first.lnum, p)); + ml_replace(first.lnum, p, TRUE); + } + + if (first.lnum < last.lnum) + { + int i; + + /* delete signs from the lines being deleted */ + for (i = first.lnum; i <= last.lnum; i++) + { + int id = buf_findsign_id(buf->bufp, (linenr_T)i); + if (id > 0) + { + nbdebug((" Deleting sign %d on line %d\n", id, i)); + buf_delsign(buf->bufp, id); + } + else + nbdebug((" No sign on line %d\n", i)); + } + + /* delete whole lines */ + nbdebug((" Deleting lines %d through %d\n", first.lnum, last.lnum)); + del_lines(last.lnum - first.lnum + 1, FALSE); + } + buf->bufp->b_changed = wasChanged; /* logically unchanged */ + netbeansFireChanges = oldFire; + netbeansSuppressNoLines = oldSuppress; + + u_blockfree(buf->bufp); + u_clearall(buf->bufp); + } + nb_reply_nil(cmdno); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "insert")) + { + pos_T *pos; + char_u *to_free; + char_u *nl; + int lnum; + pos_T old_w_cursor; + int old_b_changed; + + if (skip >= SKIP_STOP) + { + nbdebug((" Skipping %s command\n", (char *) cmd)); + nb_reply_nil(cmdno); + return OK; + } + + /* get offset */ + off = strtol((char *)args, (char **)&args, 10); + + /* get text to be inserted */ + ++args; /* skip space */ + args = to_free = (char_u *)nb_unquote(args, NULL); + + if (buf == NULL || buf->bufp == NULL) + { + die("null bufp in insert"); + retval = FAIL; + } + else if (args != NULL) + { + oldFire = netbeansFireChanges; + netbeansFireChanges = 0; + + if (curbuf != buf->bufp) + set_curbuf(buf->bufp, DOBUF_GOTO); + old_b_changed = buf->bufp->b_changed; + + if (buf->partial_line != NULL) + { + nbdebug((" Combining with partial line\n")); + off -= STRLEN(buf->partial_line); + pos = off2pos(buf->bufp, off); + if (pos && pos->col != 0) + off -= pos->col; /* want start of line */ + buf->partial_line = vim_realloc(buf->partial_line, + STRLEN(buf->partial_line) + STRLEN(args) + 1); + STRCAT(buf->partial_line, args); + vim_free(to_free); + args = buf->partial_line; + buf->partial_line = NULL; + to_free = args; + } + pos = off2pos(buf->bufp, off); + if (pos) + { + if (pos->lnum == 0) + pos->lnum = 1; + nbdebug((" POSITION: line = %d, col = %d\n", + pos->lnum, pos->col)); + } + else + { + /* if the given position is not found, assume we want + * the end of the file. See setLocAndSize HACK. + */ + pos->lnum = buf->bufp->b_ml.ml_line_count; + nbdebug((" POSITION: line = %d (EOF)\n",pos->lnum)); + } + lnum = pos->lnum; + old_w_cursor = curwin->w_cursor; + curwin->w_cursor = *pos; + + doupdate = 1; + while (*args) + { + nl = (char_u *)strchr((char *)args, '\n'); + if (!nl) + { + nbdebug((" PARTIAL[%d]: %s\n", lnum, args)); + break; + } + *nl = '\0'; + nbdebug((" INSERT[%d]: %s\n", lnum, args)); + ml_append((linenr_T)(lnum++ - 1), args, + STRLEN(args) + 1, FALSE); + args = nl + 1; + } + appended_lines_mark(pos->lnum - 1, lnum - pos->lnum); + + if (*args) + { + /* + * Incomplete line, squirrel away and wait for next insert. + */ + nbdebug((" PARTIAL-SAVED: %s\n", args)); + buf->partial_line = vim_realloc(buf->partial_line, + STRLEN(args) + 1); + STRCPY(buf->partial_line, args); + } + curwin->w_cursor = old_w_cursor; + + /* + * XXX - GRP - Is the next line right? If I've inserted + * text the buffer has been updated but not written. Will + * netbeans guarantee to write it? Even if I do a :q! ? + */ + buf->bufp->b_changed = old_b_changed; /* logically unchanged */ + netbeansFireChanges = oldFire; + + u_blockfree(buf->bufp); + u_clearall(buf->bufp); + } + vim_free(to_free); + nb_reply_nil(cmdno); /* or !error */ + } + else + { + nbdebug(("UNIMPLEMENTED FUNCTION: %s\n", cmd)); + nb_reply_nil(cmdno); + retval = FAIL; + } + } + else /* Not a function; no reply required. */ + { + /* =====================================================================*/ + if (streq((char *)cmd, "create")) + { + #if 0 /* never used */ + buf->internalname = (char *)alloc_clear(8); + sprintf(buf->internalname, "<%d>", bufno); + buf->netbeansOwns = 1; + #endif + /* not really created until setFullName */ + /* =====================================================================*/ + } + else if (streq((char *)cmd, "startDocumentListen")) + { + if (buf == NULL) + { + die("null buf in startDocumentListen"); + return FAIL; + } + buf->fireChanges = 1; + /* =====================================================================*/ + } + else if (streq((char *)cmd, "stopDocumentListen")) + { + if (buf == NULL) + { + die("null buf in stopDocumentListen"); + return FAIL; + } + buf->fireChanges = 0; + /* =====================================================================*/ + } + else if (streq((char *)cmd, "setTitle")) + { + if (buf == NULL) + { + die("null buf in setTitle"); + return FAIL; + } + vim_free(buf->displayname); + buf->displayname = nb_unquote(++args, NULL); + nbdebug((" SETTITLE %d %s\n", bufno, buf->displayname)); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "initDone")) + { + if (buf == NULL || buf->bufp == NULL) + { + die("null buf in initDone"); + return FAIL; + } + doupdate = 1; + buf->initDone = 1; + if (curbuf != buf->bufp) + set_curbuf(buf->bufp, DOBUF_GOTO); + apply_autocmds(EVENT_BUFREADPOST, 0, 0, FALSE, buf->bufp); + + /* handle any postponed key commands */ + handle_key_queue(); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "setBufferNumber") + || streq((char *)cmd, "putBufferNumber")) + { + char_u *to_free; + buf_T *bufp; + + if (buf == NULL) + { + die("null buf in setBufferNumber"); + return FAIL; + } + to_free = (char_u *)nb_unquote(++args, NULL); + if (to_free == NULL) + return FAIL; + bufp = buflist_findname(to_free); + vim_free(to_free); + if (bufp == NULL) + { + warn("File %s not found in setBufferNumber", args); + return FAIL; + } + buf->bufp = bufp; + + /* "setBufferNumber" has the side effect of jumping to the buffer + * (don't know why!). Don't do that for "putBufferNumber". */ + if (*cmd != 'p') + coloncmd(":buffer %d", bufp->b_fnum); + else + { + buf->initDone = 1; + + /* handle any postponed key commands */ + handle_key_queue(); + } + + #if 0 /* never used */ + buf->internalname = (char *)alloc_clear(8); + sprintf(buf->internalname, "<%d>", bufno); + buf->netbeansOwns = 0; + #endif + /* =====================================================================*/ + } + else if (streq((char *)cmd, "setFullName")) + { + if (buf == NULL) + { + die("null buf in setFullName"); + return FAIL; + } + vim_free(buf->displayname); + buf->displayname = nb_unquote(++args, NULL); + nbdebug((" SETFULLNAME %d %s\n", bufno, buf->displayname)); + + netbeansReadFile = 0; /* don't try to open disk file */ + do_ecmd(0, (char_u *)buf->displayname, 0, 0, ECMD_ONE, + ECMD_HIDE + ECMD_OLDBUF); + netbeansReadFile = 1; + buf->bufp = curbuf; + maketitle(); + gui_update_menus(0); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "editFile")) + { + if (buf == NULL) + { + die("null buf in editFile"); + return FAIL; + } + /* Edit a file: like create + setFullName + read the file. */ + vim_free(buf->displayname); + buf->displayname = nb_unquote(++args, NULL); + nbdebug((" EDITFILE %d %s\n", bufno, buf->displayname)); + do_ecmd(0, (char_u *)buf->displayname, NULL, NULL, ECMD_ONE, + ECMD_HIDE + ECMD_OLDBUF); + buf->bufp = curbuf; + buf->initDone = 1; + doupdate = 1; + maketitle(); + gui_update_menus(0); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "setVisible")) + { + ++args; + if (buf == NULL || buf->bufp == NULL) + { + /* warn("null bufp in setVisible"); */ + return FAIL; + } + if (streq((char *)args, "T")) + { + exarg_T exarg; + exarg.cmd = (char_u *)"goto"; + exarg.forceit = FALSE; + goto_buffer(&exarg, DOBUF_FIRST, FORWARD, buf->bufp->b_fnum); + doupdate = 1; + + /* Side effect!!!. */ + if (!gui.starting) + gui_mch_set_foreground(); + } + else + { + /* bury the buffer - not yet */ + } + /* =====================================================================*/ + } + else if (streq((char *)cmd, "raise")) + { + /* Bring gvim to the foreground. */ + if (!gui.starting) + gui_mch_set_foreground(); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "setModified")) + { + ++args; + if (buf == NULL || buf->bufp == NULL) + { + /* warn("null bufp in setModified"); */ + return FAIL; + } + if (streq((char *)args, "T")) + buf->bufp->b_changed = 1; + else + buf->bufp->b_changed = 0; + buf->modified = buf->bufp->b_changed; + /* =====================================================================*/ + } + else if (streq((char *)cmd, "setMark")) + { + /* not yet */ + /* =====================================================================*/ + } + else if (streq((char *)cmd, "showBalloon")) + { + #if defined(FEAT_BEVAL) + static char *text = NULL; + + /* + * Set up the Balloon Expression Evaluation area. + * Ignore 'ballooneval' here. + * The text pointer must remain valid for a while. + */ + if (balloonEval != NULL) + { + vim_free(text); + text = nb_unquote(++args, NULL); + if (text != NULL) + gui_mch_post_balloon(balloonEval, (char_u *)text); + } + #endif + /* =====================================================================*/ + } + else if (streq((char *)cmd, "setDot")) + { + pos_T *pos; + #ifdef NBDEBUG + char_u *s; + #endif + + ++args; + if (buf == NULL || buf->bufp == NULL) + { + die("null bufp in setDot"); + return FAIL; + } + + if (curbuf != buf->bufp) + set_curbuf(buf->bufp, DOBUF_GOTO); + #ifdef FEAT_VISUAL + /* Don't want Visual mode now. */ + if (VIsual_active) + end_visual_mode(); + #endif + #ifdef NBDEBUG + s = args; + #endif + pos = get_off_or_lnum(buf->bufp, &args); + if (pos) + curwin->w_cursor = *pos; + else + nbdebug((" BAD POSITION in setDot: %s\n", s)); + + /* gui_update_cursor(TRUE, FALSE); */ + /* update_curbuf(NOT_VALID); */ + update_topline(); /* scroll to show the line */ + update_screen(VALID); + setcursor(); + out_flush(); + gui_update_cursor(TRUE, FALSE); + gui_mch_flush(); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "close")) + { + #ifdef NBDEBUG + char *name = ""; + #endif + + if (buf == NULL) + { + die("null buf in close"); + return FAIL; + } + + #ifdef NBDEBUG + if (buf->displayname != NULL) + name = buf->displayname; + #endif + /* if (buf->bufp == NULL) */ + /* die("null bufp in close"); */ + nbdebug((" CLOSE %d: %s\n", bufno, name)); + need_mouse_correct = TRUE; + if (buf->bufp != NULL) + close_buffer(NULL, buf->bufp, 0); + doupdate = 1; + /* =====================================================================*/ + } + else if (streq((char *)cmd, "setStyle")) /* obsolete... */ + { + nbdebug((" setStyle is obsolete!")); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "setExitDelay")) + { + /* New in version 2.1. */ + exit_delay = strtol((char *)args, (char **)&args, 10); + /* =====================================================================*/ + } + else if (streq((char *)cmd, "defineAnnoType")) + { + #ifdef FEAT_SIGNS + int typeNum; + char_u *typeName; + char_u *tooltip; + char_u *glyphFile; + int use_fg = 0; + int use_bg = 0; + int fg = -1; + int bg = -1; + + if (buf == NULL) + { + die("null buf in defineAnnoType"); + return FAIL; + } + + typeNum = strtol((char *)args, (char **)&args, 10); + args = skipwhite(args); + typeName = (char_u *)nb_unquote(args, &args); + args = skipwhite(args + 1); + tooltip = (char_u *)nb_unquote(args, &args); + args = skipwhite(args + 1); + glyphFile = (char_u *)nb_unquote(args, &args); + args = skipwhite(args + 1); + if (STRNCMP(args, "none", 4) == 0) + args += 5; + else + { + use_fg = 1; + fg = strtol((char *)args, (char **)&args, 10); + } + if (STRNCMP(args, "none", 4) == 0) + args += 5; + else + { + use_bg = 1; + bg = strtol((char *)args, (char **)&args, 10); + } + if (typeName != NULL && tooltip != NULL && glyphFile != NULL) + addsigntype(buf, typeNum, typeName, tooltip, glyphFile, + use_fg, fg, use_bg, bg); + else + vim_free(typeName); + + /* don't free typeName; it's used directly in addsigntype() */ + vim_free(tooltip); + vim_free(glyphFile); + + #endif + /* =====================================================================*/ + } + else if (streq((char *)cmd, "addAnno")) + { + #ifdef FEAT_SIGNS + int serNum; + int localTypeNum; + int typeNum; + # ifdef NBDEBUG + int len; + # endif + pos_T *pos; + + if (buf == NULL || buf->bufp == NULL) + { + die("null bufp in addAnno"); + return FAIL; + } + + doupdate = 1; + + serNum = strtol((char *)args, (char **)&args, 10); + + /* Get the typenr specific for this buffer and convert it to + * the global typenumber, as used for the sign name. */ + localTypeNum = strtol((char *)args, (char **)&args, 10); + typeNum = mapsigntype(buf, localTypeNum); + + pos = get_off_or_lnum(buf->bufp, &args); + + # ifdef NBDEBUG + len = + # endif + strtol((char *)args, (char **)&args, 10); + # ifdef NBDEBUG + if (len != -1) + { + nbdebug((" partial line annotation -- Not Yet Implemented!")); + } + # endif + if (serNum >= GUARDEDOFFSET) + { + nbdebug((" too many annotations! ignoring...")); + return FAIL; + } + if (pos) + { + coloncmd(":sign place %d line=%d name=%d buffer=%d", + serNum, pos->lnum, typeNum, buf->bufp->b_fnum); + if (typeNum == curPCtype) + coloncmd(":sign jump %d buffer=%d", serNum, + buf->bufp->b_fnum); + } + /* XXX only redraw what changed. */ + redraw_later(CLEAR); + #endif + /* =====================================================================*/ + } + else if (streq((char *)cmd, "removeAnno")) + { + #ifdef FEAT_SIGNS + int serNum; + + if (buf == NULL || buf->bufp == NULL) + { + nbdebug((" null bufp in removeAnno")); + return FAIL; + } + doupdate = 1; + serNum = strtol((char *)args, (char **)&args, 10); + coloncmd(":sign unplace %d buffer=%d", + serNum, buf->bufp->b_fnum); + redraw_buf_later(buf->bufp, NOT_VALID); + #endif + /* =====================================================================*/ + } + else if (streq((char *)cmd, "moveAnnoToFront")) + { + #ifdef FEAT_SIGNS + nbdebug((" moveAnnoToFront: Not Yet Implemented!")); + #endif + /* =====================================================================*/ + } + else if (streq((char *)cmd, "guard") || streq((char *)cmd, "unguard")) + { + int len; + pos_T first; + pos_T last; + pos_T *pos; + int un = (cmd[0] == 'u'); + static int guardId = GUARDEDOFFSET; + + if (skip >= SKIP_STOP) + { + nbdebug((" Skipping %s command\n", (char *) cmd)); + return OK; + } + + if (needGraphicsInit) + nb_init_graphics(); + + if (buf == NULL || buf->bufp == NULL) + { + nbdebug((" null bufp in %s command", cmd)); + return FAIL; + } + if (curbuf != buf->bufp) + set_curbuf(buf->bufp, DOBUF_GOTO); + off = strtol((char *)args, (char **)&args, 10); + len = strtol((char *)args, 0, 10); + pos = off2pos(buf->bufp, off); + doupdate = 1; + if (!pos) + nbdebug((" no such start pos in %s, %ld\n", cmd, off)); + else + { + first = *pos; + pos = off2pos(buf->bufp, off + len - 1); + if (pos != NULL && pos->col == 0) { + /* + * In Java Swing the offset is a position between 2 + * characters. If col == 0 then we really want the + * previous line as the end. + */ + pos = off2pos(buf->bufp, off + len - 2); + } + if (!pos) + nbdebug((" no such end pos in %s, %ld\n", + cmd, off + len - 1)); + else + { + long lnum; + last = *pos; + /* set highlight for region */ + nbdebug((" %sGUARD %ld,%d to %ld,%d\n", (un) ? "UN" : "", + first.lnum, first.col, + last.lnum, last.col)); + #ifdef FEAT_SIGNS + for (lnum = first.lnum; lnum <= last.lnum; lnum++) + { + if (un) + { + /* never used */ + } + else + { + if (buf_findsigntype_id(buf->bufp, lnum, + GUARDED) == 0) + { + coloncmd( + ":sign place %d line=%d name=%d buffer=%d", + guardId++, lnum, GUARDED, + buf->bufp->b_fnum); + } + } + } + #endif + redraw_buf_later(buf->bufp, NOT_VALID); + } + } + /* =====================================================================*/ + } + else if (streq((char *)cmd, "startAtomic")) + { + inAtomic = 1; + /* =====================================================================*/ + } + else if (streq((char *)cmd, "endAtomic")) + { + inAtomic = 0; + if (needupdate) + { + doupdate = 1; + needupdate = 0; + } + /* =====================================================================*/ + } + else if (streq((char *)cmd, "version")) + { + nbdebug((" Version = %s\n", (char *) args)); + } + /* + * Unrecognized command is ignored. + */ + } + if (inAtomic && doupdate) + { + needupdate = 1; + doupdate = 0; + } + + if (buf != NULL && buf->initDone && doupdate) + { + update_screen(NOT_VALID); + setcursor(); + out_flush(); + gui_update_cursor(TRUE, FALSE); + gui_mch_flush(); + } + + return retval; + } + + + /* + * Process a vim colon command. + */ + static void + coloncmd(char *cmd, ...) + { + char buf[1024]; + va_list ap; + + va_start(ap, cmd); + vsprintf(buf, cmd, ap); + va_end(ap); + + nbdebug((" COLONCMD %s\n", buf)); + + /* ALT_INPUT_LOCK_ON; */ + do_cmdline((char_u *)buf, NULL, NULL, DOCMD_NOWAIT | DOCMD_KEYTYPED); + /* ALT_INPUT_LOCK_OFF; */ + + setcursor(); /* restore the cursor position */ + out_flush(); /* make sure output has been written */ + + gui_update_cursor(TRUE, FALSE); + XFlush(gui.dpy); + } + + #ifdef HAVE_READLINK + + /* + * Check symlinks for infinite recursion. + * "level" is for recursion control. + */ + static void + resolve_symlinks(char *filename, int level) + { + struct stat sbuf; + + if ((level > 0) && (lstat(filename, &sbuf) == 0) && (S_ISLNK(sbuf.st_mode))) + { + char buf[MAXPATHLEN+1]; + int len = readlink(filename, buf, MAXPATHLEN); + + if (len < 0 || len == MAXPATHLEN) + { + die("readlink() failed, errno = %d\n", errno); + } + else + { + buf[len] = '\0'; + + if (buf[0] == '/') + { + /* link value is absolute */ + strcpy(filename, buf); + } + else + { + /* link is relative */ + char *p = strrchr(filename, '/'); + + if (p == 0) + die("missing slash!?!"); + else + if ((p - filename) + strlen(buf) > MAXPATHLEN) + die("buffer overflow in resolve_symlinks()"); + else + strcpy(p+1, buf); + } + + /* check for symlinks in resulting path */ + resolve_symlinks(filename, level-1); + } + } + } + + #endif /* HAVE_READLINK */ + + static char *rundir = ""; + + /* + * Set rundir -- Dynamically find VIMRUNTIME dir + */ + void + netbeans_setRunDir(char *argv0) + { + char fullpath[MAXPATHLEN]; + char *p; + static char buf[MAXPATHLEN]; + + if (*argv0 == '/') + strcpy(fullpath, argv0); + else if (strchr(argv0, '/')) + { + getcwd(fullpath, MAXPATHLEN); + strcat(fullpath, "/"); + strcat(fullpath, argv0); + } + else /* no slash, have to search path */ + { + char *path = getenv("PATH"); + if (path) + { + char *pathbuf = (char *)vim_strsave((char_u *)path); + path = strtok(pathbuf, ":"); + do + { + strcpy(fullpath, path); + strcat(fullpath, "/"); + strcat(fullpath, argv0); + if (access(fullpath, X_OK) == 0) + break; + else + fullpath[0] = NUL; + } while ((path=strtok(NULL, ":")) != NULL); + vim_free(pathbuf); + } + } + + #ifdef HAVE_READLINK + /* resolve symlinks to get "real" base dir */ + resolve_symlinks(fullpath, 1000); + #endif /* HAVE_READLINK */ + + /* search backwards for "bin" or "src" dir in fullpath */ + + if (fullpath[0] != NUL) + { + p = strrchr(fullpath, '/'); + while (p) + { + if (strncmp(p, "/bin", 4) == 0 || strncmp(p, "/src", 4) == 0) + { + /* vim is in /.../bin or /.../src */ + rundir = (char *)vim_strsave((char_u *)fullpath); + break; + } + *p = NUL; + p = strrchr(fullpath, '/'); + } + } + + /* now find "doc" dir from the rundir (if $VIMRUNTIME is not set) */ + + if ((p = getenv("VIMRUNTIME")) != NULL && *p != NUL) + return; + + strcpy(buf, rundir); + strcat(buf, "/../share/vim/"); + strcat(buf, "vim61/doc"); + if (access(buf, R_OK) < 0) + { + strcpy(buf, rundir); + strcat(buf, "/../runtime/doc"); + if (access(buf, R_OK) < 0) + { + /* not found! */ + return; + } + else + { + strcpy(buf, rundir); + strcat(buf, "/../runtime"); + } + } + else + { + strcpy(buf, rundir); + strcat(buf, "/../share/vim/vim61"); + } + default_vimruntime_dir = (char_u *)buf; + } + + /* + * Initialize highlights and signs for use by netbeans (mostly obsolete) + */ + static void + nb_init_graphics(void) + { + /* char *basedir = "../../pixmaps/netbeans"; */ + /* char buf[MAXPATHLEN]; */ + + /* nbdebug(("looking for pixmaps in %s/%s\n", rundir, basedir)); */ + + /* sprintf(buf, "%s/%s", rundir, basedir); */ + + /* if (access(buf, R_OK) < 0) { */ + /* basedir = "../pixmaps/netbeans"; */ + /* sprintf(buf, "%s/%s", rundir, basedir); */ + /* nbdebug(("looking for pixmaps in %s/%s\n", rundir, basedir)); */ + /* if (access(buf, R_OK) < 0) { */ + /* fprintf(stderr, _("Cannot open pixmap directory.")); */ + /* return; */ + /* } */ + /* } */ + + coloncmd(":highlight NBGuarded guibg=Cyan guifg=Black"); + /* coloncmd(":highlight NBBreakpoint guibg=Red guifg=White"); */ + /* coloncmd(":highlight NBCurrent guibg=Blue guifg=White"); */ + /* coloncmd(":highlight NBError guibg=Yellow guifg=Black"); */ + + coloncmd(":sign define %d linehl=NBGuarded", + GUARDED); + /* coloncmd(":sign define %d icon=%s/%s/%s linehl=NBBreakpoint text=XX", */ + /* BREAKPOINT, rundir, basedir, "enabled-breakpoint.xpm"); */ + /* coloncmd(":sign define %d icon=%s/%s/%s linehl=NBCurrent text=->", */ + /* CURRENT, rundir, basedir, "currentpc.xpm"); */ + /* coloncmd(":sign define %d icon=%s/%s/%s linehl=NBError text=!!", */ + /* ERROR, rundir, basedir, "error.xpm"); */ + + /* coloncmd(":sign define %d icon=%s/%s/%s linehl=NBBreakpoint", */ + /* WASGUARDED+BREAKPOINT, rundir, basedir, "enabled-breakpoint.xpm"); */ + /* coloncmd(":sign define %d icon=%s/%s/%s linehl=NBCurrent", */ + /* WASGUARDED+CURRENT, rundir, basedir, "currentpc.xpm"); */ + /* coloncmd(":sign define %d icon=%s/%s/%s linehl=NBError", */ + /* WASGUARDED+ERROR, rundir, basedir, "error.xpm"); */ + + needGraphicsInit = 0; + } + + /* + * Convert key to netbeans name. + */ + static void + netbeans_keyname(int key, char *buf) + { + char *name = 0; + char namebuf[2]; + int ctrl = 0; + int shift = 0; + int alt = 0; + + if (mod_mask & MOD_MASK_CTRL) + ctrl = 1; + if (mod_mask & MOD_MASK_SHIFT) + shift = 1; + if (mod_mask & MOD_MASK_ALT) + alt = 1; + + + switch (key) + { + case K_F1: name = "F1"; break; + case K_S_F1: name = "F1"; shift = 1; break; + case K_F2: name = "F2"; break; + case K_S_F2: name = "F2"; shift = 1; break; + case K_F3: name = "F3"; break; + case K_S_F3: name = "F3"; shift = 1; break; + case K_F4: name = "F4"; break; + case K_S_F4: name = "F4"; shift = 1; break; + case K_F5: name = "F5"; break; + case K_S_F5: name = "F5"; shift = 1; break; + case K_F6: name = "F6"; break; + case K_S_F6: name = "F6"; shift = 1; break; + case K_F7: name = "F7"; break; + case K_S_F7: name = "F7"; shift = 1; break; + case K_F8: name = "F8"; break; + case K_S_F8: name = "F8"; shift = 1; break; + case K_F9: name = "F9"; break; + case K_S_F9: name = "F9"; shift = 1; break; + case K_F10: name = "F10"; break; + case K_S_F10: name = "F10"; shift = 1; break; + case K_F11: name = "F11"; break; + case K_S_F11: name = "F11"; shift = 1; break; + case K_F12: name = "F12"; break; + case K_S_F12: name = "F12"; shift = 1; break; + default: + if (key >= ' ' && key <= '~') + { + /* Allow ASCII characters. */ + name = namebuf; + namebuf[0] = key; + namebuf[1] = NUL; + } + else + name = "X"; + break; + } + + buf[0] = '\0'; + if (ctrl) + strcat(buf, "C"); + if (shift) + strcat(buf, "S"); + if (alt) + strcat(buf, "M"); /* META */ + if (ctrl || shift || alt) + strcat(buf, "-"); + strcat(buf, name); + } + + #ifdef FEAT_BEVAL + /* + * Function to be called for balloon evaluation. Grabs the text under the + * cursor and sends it to the debugger for evaluation. The debugger should + * respond with a showBalloon command when there is a useful result. + */ + /*ARGSUSED*/ + static void + netbeans_beval_cb( + BalloonEval *beval, + int state) + { + char_u *filename; + char_u *text; + int line; + int col; + char buf[MAXPATHLEN * 2 + 25]; + char_u *p; + + /* Don't do anything when 'ballooneval' is off or messages scrolled the + * windows up. */ + if (!p_beval || msg_scrolled > 0) + return; + + if (gui_mch_get_beval_info(beval, &filename, &line, &text, &col) == OK) + { + /* Send debugger request. Only when the text is of reasonable + * length. */ + if (text != NULL && text[0] != NUL && STRLEN(text) < MAXPATHLEN) + { + p = nb_quote(text); + if (p != NULL) + sprintf(buf, "0:balloonText=%d \"%s\"\n", cmdno, p); + vim_free(p); + nbdebug(("EVT: %s", buf)); + nb_send(buf, "netbeans_beval_cb"); + } + vim_free(text); + } + } + #endif + + /* + * Tell netbeans that the window was opened, ready for commands. + */ + void + netbeans_startup_done(void) + { + char *cmd = "0:startupDone=0\n"; + + nbdebug(("EVT: %s", cmd)); + nb_send(cmd, "netbeans_startup_done"); + + #if defined(FEAT_BEVAL) + /* + * Set up the Balloon Expression Evaluation area. + * Always create it but disable it when 'ballooneval' isn't set. + */ + balloonEval = gui_mch_create_beval_area(textArea, NULL, + netbeans_beval_cb, NULL); + if (!p_beval) + gui_mch_disable_beval_area(balloonEval); + #endif + } + + #if defined(FEAT_GUI_MOTIF) || defined(PROTO) + /* + * Tell netbeans that the window was moved or resized. + */ + void + netbeans_frame_moved(int new_x, int new_y) + { + char buf[128]; + + sprintf(buf, "0:geometry=%d %d %d %d %d\n", + cmdno, (int)Columns, (int)Rows, new_x, new_y); + nbdebug(("EVT: %s", buf)); + nb_send(buf, "netbeans_frame_moved"); + } + #endif + + /* + * Tell netbeans the user opened a file. + */ + void + netbeans_file_opened(char *filename) + { + char buffer[2*MAXPATHLEN]; + + sprintf(buffer, "0:fileOpened=%d \"%s\" %s %s\n", + 0, + filename, + "F", /* open in NetBeans */ + "F"); /* modified */ + + nbdebug(("EVT: %s", buffer)); + + nb_send(buffer, "netbeans_file_opened"); + if (p_acd && vim_chdirfile((char_u *)filename) == OK) + shorten_fnames(TRUE); + } + + /* + * Tell netbeans a file was closed. + */ + void + netbeans_file_closed(buf_T *bufp) + { + int bufno = nb_getbufno(bufp); + nbbuf_T *nbbuf = nb_get_buf(bufno); + char buffer[2*MAXPATHLEN]; + + if (!netbeansCloseFile) + { + nbdebug(("ignoring file_closed for %s\n", bufp->b_ffname)); + return; + } + + nbdebug(("netbeans_file_closed() bufno = %d, file = %s, displayname = %s\n", + bufno, bufp->b_ffname, + (nbbuf != NULL) ? nbbuf->displayname : "<>")); + + if (bufno <= 0) + return; + + sprintf(buffer, "%d:killed=%d\n", bufno, cmdno); + + nbdebug(("EVT: %s", buffer)); + + nb_send(buffer, "netbeans_file_closed"); + + if (nbbuf != NULL) + nbbuf->bufp = NULL; + } + + /* + * Get a pointer to the Netbeans buffer for Vim buffer "bufp". + * Return NULL if there is no such buffer or changes are not to be reported. + * Otherwise store the buffer number in "*bufnop". + */ + static nbbuf_T * + nb_bufp2nbbuf_fire(buf_T *bufp, int *bufnop) + { + int bufno; + nbbuf_T *nbbuf; + + if (!netbeansFireChanges) + return NULL; /* changes are not reported at all */ + + bufno = nb_getbufno(bufp); + if (bufno <= 0) + return NULL; /* file is not known to NetBeans */ + + nbbuf = nb_get_buf(bufno); + if (nbbuf != NULL && !nbbuf->fireChanges) + return NULL; /* changes in this buffer are not reported */ + + *bufnop = bufno; + return nbbuf; + } + + /* + * Tell netbeans the user inserted some text. + */ + void + netbeans_inserted( + buf_T *bufp, + linenr_T linenr, + colnr_T col, + int oldlen, + char_u *txt, + int newlen) + { + char_u *buf; + int bufno; + nbbuf_T *nbbuf; + pos_T pos; + long off; + char_u *p; + char_u *newtxt; + + nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno); + if (nbbuf == NULL) + return; + + nbbuf->modified = 1; + + pos.lnum = linenr; + pos.col = col; + + off = pos2off(bufp, &pos); + + /* nbdebug(("linenr = %d, col = %d, off = %ld\n", linenr, col, off)); */ + + buf = alloc(128 + 2*newlen); + + if (oldlen > 0) + { + /* some chars were replaced; send "remove" EVT */ + sprintf((char *)buf, "%d:remove=%d %ld %d\n", + bufno, cmdno, off, oldlen); + nbdebug(("EVT: %s", buf)); + nb_send((char *)buf, "netbeans_inserted"); + } + else if (oldlen < 0) + { + /* can't happen? */ + nbdebug(("unexpected: oldlen < 0 in netbeans_inserted")); + } + + /* send the "insert" EVT */ + newtxt = alloc(newlen + 1); + STRNCPY(newtxt, txt, newlen); + newtxt[newlen] = '\0'; + p = nb_quote(newtxt); + if (p != NULL) + sprintf((char *)buf, "%d:insert=%d %ld \"%s\"\n", bufno, cmdno, off, p); + vim_free(p); + vim_free(newtxt); + nbdebug(("EVT: %s", buf)); + nb_send((char *)buf, "netbeans_inserted"); + vim_free(buf); + } + + /* + * Tell netbeans some bytes have been removed. + */ + void + netbeans_removed( + buf_T *bufp, + linenr_T linenr, + colnr_T col, + long len) + { + char_u buf[128]; + int bufno; + nbbuf_T *nbbuf; + pos_T pos; + long off; + + nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno); + if (nbbuf == NULL) + return; + + if (len < 0) + { + nbdebug(("Negative len %ld in netbeans_removed()!", len)); + return; + } + + nbbuf->modified = 1; + + pos.lnum = linenr; + pos.col = col; + + off = pos2off(bufp, &pos); + + sprintf((char *)buf, "%d:remove=%d %ld %ld\n", bufno, cmdno, off, len); + nbdebug(("EVT: %s", buf)); + nb_send((char *)buf, "netbeans_removed"); + } + + /* + * Send netbeans an unmodufied command. + */ + void + netbeans_unmodified(buf_T *bufp) + { + char_u buf[128]; + int bufno; + nbbuf_T *nbbuf; + + nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno); + if (nbbuf == NULL) + return; + + nbbuf->modified = 0; + + sprintf((char *)buf, "%d:unmodified=%d\n", bufno, cmdno); + nbdebug(("EVT: %s", buf)); + nb_send((char *)buf, "netbeans_unmodified"); + } + + /* + * Send a keypress event back to netbeans. This usualy simulates some + * kind of function key press. + */ + void + netbeans_keycommand(int key) + { + char buf[2*MAXPATHLEN]; + int bufno; + char keyName[60]; + long off; + + if (!haveConnection) + return; + + /* convert key to netbeans name */ + netbeans_keyname(key, keyName); + + bufno = nb_getbufno(curbuf); + + if (bufno == -1) + { + nbdebug(("got keycommand for non-NetBeans buffer, opening...\n")); + sprintf(buf, "0:fileOpened=%d \"%s\" %s %s\n", 0, curbuf->b_ffname, + "T", /* open in NetBeans */ + "F"); /* modified */ + nbdebug(("EVT: %s", buf)); + nb_send(buf, "netbeans_keycommand"); + + postpone_keycommand(key); + return; + } + + /* sync the cursor position */ + off = pos2off(curbuf, &curwin->w_cursor); + sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, cmdno, off, off); + nbdebug(("EVT: %s", buf)); + nb_send(buf, "netbeans_keycommand"); + + /* now send keyCommand event */ + sprintf(buf, "%d:keyCommand=%d \"%s\"\n", bufno, cmdno, keyName); + nbdebug(("EVT: %s", buf)); + nb_send(buf, "netbeans_keycommand"); + + /* New: do both at once and include the lnum/col. */ + sprintf(buf, "%d:keyAtPos=%d \"%s\" %ld %ld/%ld\n", bufno, cmdno, keyName, + off, (long)curwin->w_cursor.lnum, (long)curwin->w_cursor.col); + nbdebug(("EVT: %s", buf)); + nb_send(buf, "netbeans_keycommand"); + } + + + /* + * Send a save event to netbeans. + */ + void + netbeans_saved(buf_T *bufp) + { + char_u buf[64]; + int bufno; + nbbuf_T *nbbuf; + + nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno); + if (nbbuf == NULL) + return; + + nbbuf->modified = 0; + + sprintf((char *)buf, "%d:save=%d\n", bufno, cmdno); + nbdebug(("EVT: %s", buf)); + nb_send((char *)buf, "netbeans_saved"); + } + + + /* + * Send remove command to netbeans (this command has been turned off). + */ + void + netbeans_deleted_all_lines(buf_T *bufp) + { + char_u buf[64]; + int bufno; + nbbuf_T *nbbuf; + + nbbuf = nb_bufp2nbbuf_fire(bufp, &bufno); + if (nbbuf == NULL) + return; + + nbbuf->modified = 1; + + sprintf((char *)buf, "%d:remove=%d 0 -1\n", bufno, cmdno); + nbdebug(("EVT(suppressed): %s", buf)); + /* nb_send(buf, "netbeans_deleted_all_lines"); */ + } + + + /* + * See if the lines are guarded. The top and bot parameters are from + * u_savecommon() and are translated to 'to' and 'from' values before + * testing. + * + * Note: top and bot are 0 based but p->lnum is 1 based. So to and from + * must be corrected for this. + */ + int + netbeans_is_guarded(linenr_T top, linenr_T bot) + { + signlist_T *p; + int lnum; + + for (p = curbuf->b_signlist; p != NULL; p = p->next) + { + for (lnum = top + 1; lnum < bot; lnum++) + if (lnum == p->lnum) + return TRUE; + } + + return FALSE; + } + + #if defined(FEAT_GUI_MOTIF) || defined(PROTO) + /* + * We have multiple signs to draw at the same location. Draw the + * multi-sign indicator instead. This is the Motif version. + */ + void + netbeans_draw_multisign_indicator(int row) + { + int i; + int y; + int x; + + x = 0; + y = row * gui.char_height + 2; + + for (i = 0; i < gui.char_height - 3; i++) + XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+2, y++); + + XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+0, y); + XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+2, y); + XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+4, y++); + XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+1, y); + XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+2, y); + XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+3, y++); + XDrawPoint(gui.dpy, gui.wid, gui.text_gc, x+2, y); + } + #endif /* FEAT_GUI_MOTIF */ + + #ifdef FEAT_GUI_GTK + /* + * We have multiple signs to draw at the same location. Draw the + * multi-sign indicator instead. This is the GTK/Gnome version. + */ + void + netbeans_draw_multisign_indicator(int row) + { + int i; + int y; + int x; + GdkDrawable *drawable = gui.drawarea->window; + + x = 0; + y = row * gui.char_height + 2; + + for (i = 0; i < gui.char_height - 3; i++) + gdk_draw_point(drawable, gui.text_gc, x+2, y++); + + gdk_draw_point(drawable, gui.text_gc, x+0, y); + gdk_draw_point(drawable, gui.text_gc, x+2, y); + gdk_draw_point(drawable, gui.text_gc, x+4, y++); + gdk_draw_point(drawable, gui.text_gc, x+1, y); + gdk_draw_point(drawable, gui.text_gc, x+2, y); + gdk_draw_point(drawable, gui.text_gc, x+3, y++); + gdk_draw_point(drawable, gui.text_gc, x+2, y); + } + #endif /* FEAT_GUI_GTK */ + + /* + * If the mouse is clicked in the gutter of a line with multiple + * annotations, cycle through the set of signs. + */ + void + netbeans_gutter_click(linenr_T lnum) + { + signlist_T *p; + + for (p = curbuf->b_signlist; p != NULL; p = p->next) + { + if (p->lnum == lnum && p->next && p->next->lnum == lnum) + { + signlist_T *tail; + /* remove "p" from list, reinsert it at the tail of the sublist */ + if (p->prev) + p->prev->next = p->next; + else + curbuf->b_signlist = p->next; + p->next->prev = p->prev; + /* now find end of sublist and insert p */ + for (tail = p->next; + tail->next && tail->next->lnum == lnum && tail->next->id < GUARDEDOFFSET; + tail = tail->next) + ; + /* tail now points to last entry with same lnum (except + * that "guarded" annotations are always last) + */ + p->next = tail->next; + if (tail->next) + tail->next->prev = p; + p->prev = tail; + tail->next = p; + update_debug_sign(curbuf, lnum); + break; + } + } + } + + + /* + * Add a sign of the reqested type at the requested location. + * + * Reverse engineering: + * Apparently an annotation is defined the first time it is used in a buffer. + * When the same annotation is used in two buffers, the second time we do not + * need to define a new sign name but reuse the existing one. But since the + * ID number used in the second buffer starts counting at one again, a mapping + * is made from the ID specifically for the buffer to the global sign name + * (which is a number). + * + * globalsignmap[] stores the signs that have been defined globally. + * buf->signmapused[] maps buffer-local annotation IDs to an index in + * globalsignmap[]. + */ + /*ARGSUSED*/ + static void + addsigntype( + nbbuf_T *buf, + int typeNum, + char_u *typeName, + char_u *tooltip, + char_u *glyphFile, + int use_fg, + int fg, + int use_bg, + int bg) + { + char fgbuf[32]; + char bgbuf[32]; + int i, j; + + for (i = 0; i < globalsignmapused; i++) + if (STRCMP(typeName, globalsignmap[i]) == 0) + break; + + if (i == globalsignmapused) /* not found; add it to global map */ + { + nbdebug(("DEFINEANNOTYPE(%d,%s,%s,%s,%d,%d)\n", + typeNum, typeName, tooltip, glyphFile, fg, bg)); + if (use_fg || use_bg) + { + sprintf(fgbuf, "guifg=#%06x", fg & 0xFFFFFF); + sprintf(bgbuf, "guibg=#%06x", bg & 0xFFFFFF); + + coloncmd(":highlight NB_%s %s %s", typeName, (use_fg) ? fgbuf : "", + (use_bg) ? bgbuf : ""); + if (*glyphFile == NUL) + /* no glyph, line highlighting only */ + coloncmd(":sign define %d linehl=NB_%s", i + 1, typeName); + else if (STRLEN(glyphFile) <= 2) + /* two-character glyph name, use as text glyph with texthl */ + coloncmd(":sign define %d text=%s texthl=NB_%s", i + 1, + glyphFile, typeName); + else + /* glyph, line highlighting */ + coloncmd(":sign define %d icon=%s linehl=NB_%s", i + 1, + glyphFile, typeName); + } + else + /* glyph, no line highlighting */ + coloncmd(":sign define %d icon=%s", i + 1, glyphFile); + + if (STRCMP(typeName,"CurrentPC") == 0) + curPCtype = typeNum; + + if (globalsignmapused == globalsignmaplen) + { + if (globalsignmaplen == 0) /* first allocation */ + { + globalsignmaplen = 20; + globalsignmap = (char **)alloc_clear(globalsignmaplen*sizeof(char *)); + } + else /* grow it */ + { + int incr; + int oldlen = globalsignmaplen; + + globalsignmaplen *= 2; + incr = globalsignmaplen - oldlen; + globalsignmap = (char **)vim_realloc(globalsignmap, + globalsignmaplen * sizeof(char *)); + memset(globalsignmap + oldlen, 0, incr * sizeof(char *)); + } + } + + globalsignmap[i] = (char *)typeName; + globalsignmapused = i + 1; + } + + /* check local map; should *not* be found! */ + for (j = 0; j < buf->signmapused; j++) + if (buf->signmap[j] == i + 1) + return; + + /* add to local map */ + if (buf->signmapused == buf->signmaplen) + { + if (buf->signmaplen == 0) /* first allocation */ + { + buf->signmaplen = 5; + buf->signmap = (int *)alloc_clear(buf->signmaplen * sizeof(int *)); + } + else /* grow it */ + { + int incr; + int oldlen = buf->signmaplen; + buf->signmaplen *= 2; + incr = buf->signmaplen - oldlen; + buf->signmap = (int *)vim_realloc(buf->signmap, + buf->signmaplen*sizeof(int *)); + memset(buf->signmap + oldlen, 0, incr * sizeof(int *)); + } + } + + buf->signmap[buf->signmapused++] = i + 1; + + } + + + /* + * See if we have the requested sign type in the buffer. + */ + static int + mapsigntype(nbbuf_T *buf, int localsigntype) + { + if (--localsigntype >= 0 && localsigntype < buf->signmapused) + return buf->signmap[localsigntype]; + + return 0; + } + + + /* + * Compute length of buffer, don't print anything. + */ + static long + get_buf_size(buf_T *bufp) + { + linenr_T lnum; + long char_count = 0; + int eol_size; + long last_check = 100000L; + + if (bufp->b_ml.ml_flags & ML_EMPTY) + return 0; + else + { + if (get_fileformat(bufp) == EOL_DOS) + eol_size = 2; + else + eol_size = 1; + for (lnum = 1; lnum <= bufp->b_ml.ml_line_count; ++lnum) + { + char_count += STRLEN(ml_get(lnum)) + eol_size; + /* Check for a CTRL-C every 100000 characters */ + if (char_count > last_check) + { + ui_breakcheck(); + if (got_int) + return char_count; + last_check = char_count + 100000L; + } + } + /* Correction for when last line doesn't have an EOL. */ + if (!bufp->b_p_eol && bufp->b_p_bin) + char_count -= eol_size; + } + + return char_count; + } + + /* + * Convert character offset to lnum,col + */ + static pos_T * + off2pos(buf_T *buf, long offset) + { + linenr_T lnum; + static pos_T pos; + + pos.lnum = 0; + pos.col = 0; + #ifdef FEAT_VIRTUALEDIT + pos.coladd = 0; + #endif + + if (!(buf->b_ml.ml_flags & ML_EMPTY)) + { + if ((lnum = ml_find_line_or_offset(buf, (linenr_T)0, &offset)) < 0) + return NULL; + pos.lnum = lnum; + pos.col = offset; + } + + return &pos; + } + + /* + * Convert an argument in the form "1234" to an offset and compute the + * lnum/col from it. Convert an argument in the form "123/12" directly to a + * lnum/col. + * "argp" is advanced to after the argument. + * Return a pointer to the position, NULL if something is wrong. + */ + static pos_T * + get_off_or_lnum(buf_T *buf, char_u **argp) + { + static pos_T mypos; + long off; + + off = strtol((char *)*argp, (char **)argp, 10); + if (**argp == '/') + { + mypos.lnum = (linenr_T)off; + ++*argp; + mypos.col = strtol((char *)*argp, (char **)argp, 10); + #ifdef FEAT_VIRTUALEDIT + mypos.coladd = 0; + #endif + return &mypos; + } + return off2pos(buf, off); + } + + + /* + * Convert lnum,col to character offset + */ + static long + pos2off(buf_T *buf, pos_T *pos) + { + long offset = 0; + + if (!(buf->b_ml.ml_flags & ML_EMPTY)) + { + if ((offset = ml_find_line_or_offset(buf, pos->lnum, 0)) < 0) + return 0; + offset += pos->col; + } + + return offset; + } + + + #if defined(FEAT_GUI_MOTIF) || defined(PROTO) + /* + * This function fills in the XRectangle object with the current + * x,y coordinates and height, width so that an XtVaSetValues to + * the same shell of those resources will restore the window to its + * formar position and dimensions. + * + * Note: This function may fail, in which case the XRectangle will + * be unchanged. Be sure to have the XRectangle set with the + * proper values for a failed condition prior to calling this + * function. + */ + void + shellRectangle(Widget shell, XRectangle *r) + { + Window rootw, shellw, child, parentw; + int absx, absy; + XWindowAttributes a; + Window *children; + unsigned int childrenCount; + + shellw = XtWindow(shell); + if (shellw == 0) + return; + for (;;) + { + XQueryTree(XtDisplay(shell), shellw, &rootw, &parentw, + &children, &childrenCount); + XFree(children); + if (parentw == rootw) + break; + shellw = parentw; + } + XGetWindowAttributes(XtDisplay(shell), shellw, &a); + XTranslateCoordinates(XtDisplay(shell), shellw, a.root, 0, 0, + &absx, &absy, &child); + r->x = absx; + r->y = absy; + XtVaGetValues(shell, XmNheight, &r->height, + XmNwidth, &r->width, NULL); + } + #endif *** ../vim61.365/src/normal.c Thu Feb 20 21:36:44 2003 --- src/normal.c Mon Mar 3 20:55:23 2003 *************** *** 165,170 **** --- 165,173 ---- #ifdef FEAT_SNIFF static void nv_sniff __ARGS((cmdarg_T *cap)); #endif + #ifdef FEAT_NETBEANS_INTG + static void nv_nbcmd __ARGS((cmdarg_T *cap)); + #endif /* * Function to be called for a Normal or Visual mode command. *************** *** 413,418 **** --- 416,424 ---- #ifdef FEAT_SNIFF {K_SNIFF, nv_sniff, 0, 0}, #endif + #ifdef FEAT_NETBEANS_INTG + {K_F21, nv_nbcmd, NV_NCH_ALW, 0}, + #endif }; /* Number of commands in nv_cmds[]. */ *************** *** 2993,2998 **** --- 2999,3020 ---- char_u **string; int find_type; { + return find_ident_at_pos(curwin, curwin->w_cursor.lnum, + curwin->w_cursor.col, string, find_type); + } + + /* + * Like find_ident_under_cursor(), but for any window and any position. + * However: Uses 'iskeyword' from the current window!. + */ + int + find_ident_at_pos(wp, lnum, startcol, string, find_type) + win_T *wp; + linenr_T lnum; + colnr_T startcol; + char_u **string; + int find_type; + { char_u *ptr; int col = 0; /* init to shut up GCC */ int i; *************** *** 3006,3018 **** * if i == 0: try to find an identifier * if i == 1: try to find any non-white string */ ! ptr = ml_get_curline(); for (i = (find_type & FIND_IDENT) ? 0 : 1; i < 2; ++i) { /* * 1. skip to start of identifier/string */ ! col = curwin->w_cursor.col; #ifdef FEAT_MBYTE if (has_mbyte) { --- 3028,3040 ---- * if i == 0: try to find an identifier * if i == 1: try to find any non-white string */ ! ptr = ml_get_buf(wp->w_buffer, lnum, FALSE); for (i = (find_type & FIND_IDENT) ? 0 : 1; i < 2; ++i) { /* * 1. skip to start of identifier/string */ ! col = startcol; #ifdef FEAT_MBYTE if (has_mbyte) { *************** *** 4805,4811 **** /* * Now grab the chars in the identifier */ ! if (cmdchar == '*' || cmdchar == '#') aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\"); else if (cmdchar == 'K' && *p_kp != NUL) aux_ptr = (char_u *)" \t\\\"|!"; --- 4827,4835 ---- /* * Now grab the chars in the identifier */ ! if (cmdchar == '*') ! aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\"); ! else if (cmdchar == '#') aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\"); else if (cmdchar == 'K' && *p_kp != NUL) aux_ptr = (char_u *)" \t\\\"|!"; *************** *** 8107,8111 **** --- 8131,8144 ---- cmdarg_T *cap; { ProcessSniffRequests(); + } + #endif + + #ifdef FEAT_NETBEANS_INTG + static void + nv_nbcmd(cap) + cmdarg_T *cap; + { + netbeans_keycommand(cap->nchar); } #endif *** ../vim61.365/src/option.c Mon Feb 24 11:29:15 2003 --- src/option.c Tue Mar 4 20:18:38 2003 *************** *** 326,331 **** --- 326,336 ---- (char_u *)NULL, PV_NONE, #endif {(char_u *)FALSE, (char_u *)0L}}, + #if defined(FEAT_NETBEANS_INTG) || defined(FEAT_SUN_WORKSHOP) + {"autochdir", "acd", P_BOOL|P_VI_DEF, + (char_u *)&p_acd, PV_NONE, + {(char_u *)FALSE, (char_u *)0L}}, + #endif {"autoindent", "ai", P_BOOL|P_VI_DEF, (char_u *)&p_ai, PV_AI, {(char_u *)FALSE, (char_u *)0L}}, *************** *** 390,396 **** (char_u *)&p_bdlay, PV_NONE, {(char_u *)600L, (char_u *)0L}}, #endif ! #ifdef FEAT_SUN_WORKSHOP {"ballooneval", "beval",P_BOOL|P_VI_DEF|P_NO_MKRC, (char_u *)&p_beval, PV_NONE, {(char_u*)FALSE, (char_u *)0L}}, --- 395,402 ---- (char_u *)&p_bdlay, PV_NONE, {(char_u *)600L, (char_u *)0L}}, #endif ! #if defined(FEAT_BEVAL) && (defined(FEAT_SUN_WORKSHOP) \ ! || defined(FEAT_NETBEANS_INTG)) {"ballooneval", "beval",P_BOOL|P_VI_DEF|P_NO_MKRC, (char_u *)&p_beval, PV_NONE, {(char_u*)FALSE, (char_u *)0L}}, *************** *** 5865,5871 **** p_wiv = (*T_XS != NUL); } ! #ifdef FEAT_SUN_WORKSHOP else if ((int *)varp == &p_beval) { extern BalloonEval *balloonEval; --- 5873,5880 ---- p_wiv = (*T_XS != NUL); } ! #if defined(FEAT_BEVAL) && (defined(FEAT_SUN_WORKSHOP) \ ! || defined(FEAT_NETBEANS_INTG)) else if ((int *)varp == &p_beval) { extern BalloonEval *balloonEval; *************** *** 5875,5880 **** --- 5884,5896 ---- else gui_mch_disable_beval_area(balloonEval); } + + else if ((int *)varp == &p_acd) + { + if (p_acd && curbuf->b_ffname != NULL + && vim_chdirfile(curbuf->b_ffname) == OK) + shorten_fnames(TRUE); + } #endif #ifdef FEAT_DIFF *** ../vim61.365/src/option.h Sun Oct 13 20:08:14 2002 --- src/option.h Tue Mar 4 20:18:50 2003 *************** *** 281,286 **** --- 281,289 ---- #ifdef FEAT_RIGHTLEFT EXTERN long p_aleph; /* 'aleph' */ #endif + #if defined(FEAT_NETBEANS_INTG) || defined(FEAT_SUN_WORKSHOP) + EXTERN int p_acd; /* 'autochdir' */ + #endif EXTERN int p_ar; /* 'autoread' */ EXTERN int p_aw; /* 'autowrite' */ EXTERN int p_awa; /* 'autowriteall' */ *************** *** 295,303 **** #endif #ifdef FEAT_BEVAL EXTERN long p_bdlay; /* 'balloondelay' */ ! #endif ! #ifdef FEAT_SUN_WORKSHOP EXTERN int p_beval; /* 'ballooneval' */ #endif #ifdef FEAT_BROWSE EXTERN char_u *p_bsdir; /* 'browsedir' */ --- 298,306 ---- #endif #ifdef FEAT_BEVAL EXTERN long p_bdlay; /* 'balloondelay' */ ! # if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) EXTERN int p_beval; /* 'ballooneval' */ + # endif #endif #ifdef FEAT_BROWSE EXTERN char_u *p_bsdir; /* 'browsedir' */ *** ../vim61.365/src/proto/buffer.pro Sun Oct 13 18:48:35 2002 --- src/proto/buffer.pro Sat Mar 8 15:47:27 2003 *************** *** 49,60 **** int read_viminfo_bufferlist __ARGS((vir_T *virp, int writing)); void write_viminfo_bufferlist __ARGS((FILE *fp)); char *buf_spname __ARGS((buf_T *buf)); ! int buf_addsign __ARGS((buf_T *buf, int id, linenr_T lnum, int typenr)); int buf_change_sign_type __ARGS((buf_T *buf, int markId, int typenr)); ! int_u buf_getsigntype __ARGS((buf_T *buf, linenr_T lnum)); linenr_T buf_delsign __ARGS((buf_T *buf, int id)); int buf_findsign __ARGS((buf_T *buf, int id)); int buf_findsign_id __ARGS((buf_T *buf, linenr_T lnum)); void buf_delete_all_signs __ARGS((void)); void sign_list_placed __ARGS((buf_T *rbuf)); void sign_mark_adjust __ARGS((linenr_T line1, linenr_T line2, long amount, long amount_after)); --- 49,62 ---- int read_viminfo_bufferlist __ARGS((vir_T *virp, int writing)); void write_viminfo_bufferlist __ARGS((FILE *fp)); char *buf_spname __ARGS((buf_T *buf)); ! void buf_addsign __ARGS((buf_T *buf, int id, linenr_T lnum, int typenr)); int buf_change_sign_type __ARGS((buf_T *buf, int markId, int typenr)); ! int_u buf_getsigntype __ARGS((buf_T *buf, linenr_T lnum, int type)); linenr_T buf_delsign __ARGS((buf_T *buf, int id)); int buf_findsign __ARGS((buf_T *buf, int id)); int buf_findsign_id __ARGS((buf_T *buf, linenr_T lnum)); + int buf_findsigntype_id __ARGS((buf_T *buf, linenr_T lnum, int typenr)); + int buf_signcount __ARGS((buf_T *buf, linenr_T lnum)); void buf_delete_all_signs __ARGS((void)); void sign_list_placed __ARGS((buf_T *rbuf)); void sign_mark_adjust __ARGS((linenr_T line1, linenr_T line2, long amount, long amount_after)); *** ../vim61.365/src/proto/gui_beval.pro Fri Mar 22 21:41:25 2002 --- src/proto/gui_beval.pro Thu Mar 6 21:26:51 2003 *************** *** 3,8 **** void gui_mch_destroy_beval_area __ARGS((BalloonEval *beval)); void gui_mch_enable_beval_area __ARGS((BalloonEval *beval)); void gui_mch_disable_beval_area __ARGS((BalloonEval *beval)); ! Boolean gui_mch_get_beval_info __ARGS((BalloonEval *beval, char_u **filename, int *line, char_u **text, int *idx)); void gui_mch_post_balloon __ARGS((BalloonEval *beval, char_u *mesg)); /* vim: set ft=c : */ --- 3,8 ---- void gui_mch_destroy_beval_area __ARGS((BalloonEval *beval)); void gui_mch_enable_beval_area __ARGS((BalloonEval *beval)); void gui_mch_disable_beval_area __ARGS((BalloonEval *beval)); ! int gui_mch_get_beval_info __ARGS((BalloonEval *beval, char_u **filename, int *line, char_u **text, int *idx)); void gui_mch_post_balloon __ARGS((BalloonEval *beval, char_u *mesg)); /* vim: set ft=c : */ *** ../vim61.365/src/proto/gui_gtk_x11.pro Fri Mar 22 21:41:28 2002 --- src/proto/gui_gtk_x11.pro Thu Mar 6 21:26:54 2003 *************** *** 57,60 **** --- 57,63 ---- void gui_mch_setmouse __ARGS((int x, int y)); void gui_mch_mousehide __ARGS((int hide)); void mch_set_mouse_shape __ARGS((int shape)); + void gui_mch_drawsign __ARGS((int row, int col, int typenr)); + void *gui_mch_register_sign __ARGS((char_u *signfile)); + void gui_mch_destroy_sign __ARGS((void *sign)); /* vim: set ft=c : */ *** ../vim61.365/src/proto/netbeans.pro Sat Mar 8 17:24:28 2003 --- src/proto/netbeans.pro Thu Mar 6 21:26:52 2003 *************** *** 0 **** --- 1,21 ---- + /* netbeans.c */ + void netbeans_Xt_connect __ARGS((void *context)); + void netbeans_gtk_connect __ARGS((void)); + void netbeans_end __ARGS((void)); + void netbeans_setRunDir __ARGS((char *argv0)); + void netbeans_startup_done __ARGS((void)); + void netbeans_frame_moved __ARGS((int new_x, int new_y)); + void netbeans_file_opened __ARGS((char *filename)); + void netbeans_file_closed __ARGS((buf_T *bufp)); + void netbeans_inserted __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, int oldlen, char_u *txt, int newlen)); + void netbeans_removed __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, long len)); + void netbeans_unmodified __ARGS((buf_T *bufp)); + void netbeans_keycommand __ARGS((int key)); + void netbeans_saved __ARGS((buf_T *bufp)); + void netbeans_deleted_all_lines __ARGS((buf_T *bufp)); + int netbeans_is_guarded __ARGS((linenr_T top, linenr_T bot)); + void netbeans_draw_multisign_indicator __ARGS((int row)); + void netbeans_draw_multisign_indicator __ARGS((int row)); + void netbeans_gutter_click __ARGS((linenr_T lnum)); + void shellRectangle __ARGS((Widget shell, XRectangle *r)); + /* vim: set ft=c : */ *** ../vim61.365/src/proto/normal.pro Sun Jul 21 21:47:39 2002 --- src/proto/normal.pro Thu Mar 6 21:26:45 2003 *************** *** 8,13 **** --- 8,14 ---- void reset_VIsual_and_resel __ARGS((void)); void reset_VIsual __ARGS((void)); int find_ident_under_cursor __ARGS((char_u **string, int find_type)); + int find_ident_at_pos __ARGS((win_T *wp, linenr_T lnum, colnr_T startcol, char_u **string, int find_type)); void clear_showcmd __ARGS((void)); int add_to_showcmd __ARGS((int c)); void add_to_showcmd_c __ARGS((int c)); *** ../vim61.365/src/proto/ui.pro Sun Jan 5 22:14:46 2003 --- src/proto/ui.pro Thu Mar 6 21:26:50 2003 *************** *** 55,60 **** --- 55,61 ---- int mouse_comp_pos __ARGS((win_T *win, int *rowp, int *colp, linenr_T *lnump)); win_T *mouse_find_win __ARGS((int *rowp, int *colp)); int get_fpos_of_mouse __ARGS((pos_T *mpos)); + int vcol2col __ARGS((win_T *wp, linenr_T lnum, int vcol)); void ui_focus_change __ARGS((int in_focus)); void im_save_status __ARGS((long *psave)); /* vim: set ft=c : */ *** ../vim61.365/src/proto.h Mon Jan 6 21:55:57 2003 --- src/proto.h Thu Feb 13 20:11:49 2003 *************** *** 199,204 **** --- 199,207 ---- # ifdef FEAT_SUN_WORKSHOP # include "workshop.pro" # endif + # ifdef FEAT_NETBEANS_INTG + # include "netbeans.pro" + # endif # endif /* FEAT_GUI */ # ifdef FEAT_OLE *** ../vim61.365/src/screen.c Tue Feb 25 21:13:03 2003 --- src/screen.c Sat Mar 8 15:09:21 2003 *************** *** 2414,2422 **** #ifdef FEAT_LINEBREAK int need_showbreak = FALSE; #endif - #ifdef FEAT_SIGNS - int_u sign_typenr; /* sign type (if signs are used) */ - #endif #if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) # define LINE_ATTR int line_attr = 0; /* atrribute for the whole line */ --- 2415,2420 ---- *************** *** 2633,2642 **** #ifdef LINE_ATTR # ifdef FEAT_SIGNS ! /* Draw a sign at the start of the line and/or highlight the line. */ ! sign_typenr = buf_getsigntype(wp->w_buffer, lnum); ! if (sign_typenr != 0) ! line_attr = sign_get_attr(sign_typenr, TRUE); # endif # if defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS) /* Highlight the current line in the quickfix window. */ --- 2631,2640 ---- #ifdef LINE_ATTR # ifdef FEAT_SIGNS ! /* If this line has a sign with line highlighting set line_attr. */ ! v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL); ! if (v != 0) ! line_attr = sign_get_attr((int)v, TRUE); # endif # if defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS) /* Highlight the current line in the quickfix window. */ *************** *** 2850,2888 **** if (draw_state == WL_SIGN - 1 && n_extra == 0) { draw_state = WL_SIGN; ! if (wp->w_buffer->b_signlist != NULL # ifdef FEAT_DIFF && filler_todo <= 0 # endif ! ) { /* Draw two bytes with the sign value or blank. */ ! if (sign_typenr == 0 || row > startrow) ! { ! c_extra = ' '; ! char_attr = 0; ! } ! else { # ifdef FEAT_SIGN_ICONS ! if (gui.in_use && sign_get_image(sign_typenr) != NULL) { /* Use the image in this position. */ c_extra = SIGN_BYTE; ! char_attr = sign_typenr; } ! else # endif { ! p_extra = sign_get_text(sign_typenr); ! if (p_extra == NULL) ! c_extra = ' '; ! else ! c_extra = NUL; ! char_attr = sign_get_attr(sign_typenr, FALSE); } } - n_extra = 2; } } #endif --- 2848,2900 ---- if (draw_state == WL_SIGN - 1 && n_extra == 0) { draw_state = WL_SIGN; ! /* Show the sign column when there are any signs in this ! * buffer or when using Netbeans. */ ! if ((wp->w_buffer->b_signlist != NULL ! # ifdef FEAT_NETBEANS_INTG ! || usingNetbeans ! # endif ! ) # ifdef FEAT_DIFF && filler_todo <= 0 # endif ! ) { + int_u text_sign; + # ifdef FEAT_SIGN_ICONS + int_u icon_sign; + # endif + /* Draw two bytes with the sign value or blank. */ ! c_extra = ' '; ! char_attr = 0; ! n_extra = 2; ! ! if (row == startrow) { + text_sign = buf_getsigntype(wp->w_buffer, lnum, + SIGN_TEXT); # ifdef FEAT_SIGN_ICONS ! icon_sign = buf_getsigntype(wp->w_buffer, lnum, ! SIGN_ICON); ! if (gui.in_use && icon_sign != 0) { /* Use the image in this position. */ c_extra = SIGN_BYTE; ! # ifdef FEAT_NETBEANS_INTG ! if (buf_signcount(wp->w_buffer, lnum) > 1) ! c_extra = MULTISIGN_BYTE; ! # endif ! char_attr = icon_sign; } ! else if (text_sign != 0) # endif { ! p_extra = sign_get_text(text_sign); ! c_extra = NUL; ! char_attr = sign_get_attr(text_sign, FALSE); } } } } #endif *** ../vim61.365/src/structs.h Tue Jan 28 22:17:41 2003 --- src/structs.h Sat Mar 8 13:01:45 2003 *************** *** 494,500 **** --- 494,509 ---- linenr_T lnum; /* line number which has this sign */ int typenr; /* typenr of sign */ signlist_T *next; /* next signlist entry */ + # ifdef FEAT_NETBEANS_INTG + signlist_T *prev; /* previous entry -- for easy reordering */ + # endif }; + + /* type argument for buf_getsigntype() */ + #define SIGN_ANY 0 + #define SIGN_LINEHL 1 + #define SIGN_ICON 2 + #define SIGN_TEXT 3 #endif /* *** ../vim61.365/src/ui.c Wed Feb 19 11:21:27 2003 --- src/ui.c Mon Mar 3 12:48:17 2003 *************** *** 1462,1480 **** * descriptions which would otherwise overflow. The buffer is considered full * when only this extra space (or part of it) remains. */ ! #ifdef VMS ! # define INBUFLEN 10000 /* for proper cut/paste between X windows in ch. mode */ ! #else ! # if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_CLIENTSERVER) /* ! * Sun WorkShop stuffs debugger commands into the input buffer. This requires ! * a larger buffer... * (Madsen) Go with this for remote input as well ... */ ! # define INBUFLEN 4096 ! # else ! # define INBUFLEN 250 ! # endif #endif static char_u inbuf[INBUFLEN + MAX_KEY_CODE_LEN]; --- 1463,1478 ---- * descriptions which would otherwise overflow. The buffer is considered full * when only this extra space (or part of it) remains. */ ! #if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \ ! || defined(FEAT_CLIENTSERVER) /* ! * Sun WorkShop and NetBeans stuff debugger commands into the input buffer. ! * This requires a larger buffer... * (Madsen) Go with this for remote input as well ... */ ! # define INBUFLEN 4096 ! #else ! # define INBUFLEN 250 #endif static char_u inbuf[INBUFLEN + MAX_KEY_CODE_LEN]; *************** *** 2689,2695 **** --- 2680,2691 ---- /* skip line number and fold column in front of the line */ col -= win_col_off(win); if (col < 0) + { + #ifdef FEAT_NETBEANS_INTG + netbeans_gutter_click(lnum); + #endif col = 0; + } *colp = col; *rowp = row; *************** *** 2697,2703 **** return retval; } ! #ifdef FEAT_WINDOWS /* * Find the window at screen position "*rowp" and "*colp". The positions are * updated to become relative to the top-left of the window. --- 2693,2699 ---- return retval; } ! #if defined(FEAT_WINDOWS) || defined(PROTO) /* * Find the window at screen position "*rowp" and "*colp". The positions are * updated to become relative to the top-left of the window. *************** *** 2751,2758 **** pos_T *mpos; { win_T *wp; - int count; - char_u *ptr; int row = mouse_row; int col = mouse_col; --- 2747,2752 ---- *************** *** 2782,2806 **** if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum)) return IN_STATUS_LINE; /* past bottom */ /* try to advance to the specified column */ ! mpos->col = 0; ! count = 0; ! ptr = ml_get_buf(wp->w_buffer, mpos->lnum, FALSE); ! while (count <= col && *ptr != NUL) { ! ++mpos->col; count += win_lbr_chartabsize(wp, ptr, count, NULL); ! #ifdef FEAT_MBYTE if (has_mbyte) ptr += (*mb_ptr2len_check)(ptr); else ! #endif ++ptr; } ! if (mpos->col == 0) ! return IN_BUFFER; ! --mpos->col; ! return IN_BUFFER; } #endif --- 2776,2816 ---- if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum)) return IN_STATUS_LINE; /* past bottom */ + mpos->col = vcol2col(wp, mpos->lnum, col); + + if (mpos->col > 0) + --mpos->col; + return IN_BUFFER; + } + + /* + * Convert a virtual (screen) column to a character column. + * The first column is one. + */ + int + vcol2col(wp, lnum, vcol) + win_T *wp; + linenr_T lnum; + int vcol; + { /* try to advance to the specified column */ ! int col = 0; ! int count = 0; ! char_u *ptr; ! ! ptr = ml_get_buf(wp->w_buffer, lnum, FALSE); ! while (count <= vcol && *ptr != NUL) { ! ++col; count += win_lbr_chartabsize(wp, ptr, count, NULL); ! # ifdef FEAT_MBYTE if (has_mbyte) ptr += (*mb_ptr2len_check)(ptr); else ! # endif ++ptr; } ! return col; } #endif *** ../vim61.365/src/undo.c Sat Aug 24 23:24:51 2002 --- src/undo.c Thu Feb 13 20:20:38 2003 *************** *** 180,185 **** --- 180,197 ---- } #endif + #ifdef FEAT_NETBEANS_INTG + /* + * Netbeans defines areas that cannot be modified. Bail out here when + * trying to change text in a guarded area. + */ + if (usingNetbeans && netbeans_is_guarded(top, bot)) + { + EMSG(_(e_guarded)); + return FAIL; + } + #endif + #ifdef FEAT_AUTOCMD /* * Saving text for undo means we are going to make a change. Give a *** ../vim61.365/src/vim.h Mon Feb 24 11:29:15 2003 --- src/vim.h Sun Feb 16 15:57:09 2003 *************** *** 1656,1661 **** --- 1656,1666 ---- #define SIGN_BYTE 1 /* byte value used where sign is displayed; attribute value is sign type */ + #ifdef FEAT_NETBEANS_INTG + # define MULTISIGN_BYTE 2 /* byte value used where sign is displayed if + multiple signs exist on the line */ + #endif + #if defined(FEAT_GUI) && defined(FEAT_XCLIPBOARD) # define X_DISPLAY (gui.in_use ? gui.dpy : xterm_dpy) #else *************** *** 1664,1669 **** --- 1669,1680 ---- # else # define X_DISPLAY xterm_dpy # endif + #endif + + #ifdef NBDEBUG /* Netbeans debugging. */ + # include "nbdebug.h" + #else + # define nbdebug(a) #endif #endif /* VIM__H */ *** ../vim61.365/src/window.c Wed Feb 26 21:12:31 2003 --- src/window.c Sat Mar 8 16:09:47 2003 *************** *** 2845,2850 **** --- 2845,2857 ---- int undo_sync; { win_enter_ext(wp, undo_sync, FALSE); + #if defined(FEAT_NETBEANS_INTG) || defined(FEAT_SUN_WORKSHOP) + /* Change directories when the acd option is set on and after + * switching windows. */ + if (p_acd && curbuf->b_ffname != NULL + && vim_chdirfile(curbuf->b_ffname) == OK) + shorten_fnames(TRUE); + #endif } /* *** ../vim61.365/src/workshop.c Wed Oct 24 14:14:41 2001 --- src/workshop.c Tue Mar 4 20:19:34 2003 *************** *** 57,63 **** --- 57,65 ---- #endif static void load_window(char *, int lnum); static void warp_to_pc(int); + #ifdef FEAT_BEVAL static void bevalCB(BalloonEval *, int); + #endif static char *fixAccelText(char *); static void addMenu(char *, char *, char *); static char *lookupVerb(char *, int); *************** *** 217,222 **** --- 219,225 ---- wstrace("workshop_load_file(%s, %d)\n", filename, line); #endif + #ifdef FEAT_BEVAL if (balloonEval == NULL) { /* *************** *** 227,232 **** --- 230,236 ---- if (!p_beval) gui_mch_disable_beval_area(balloonEval); } + #endif load_window(filename, line); } *************** *** 1556,1561 **** --- 1560,1566 ---- return NULL; } + #ifdef FEAT_BEVAL static void bevalCB( BalloonEval *beval, *************** *** 1573,1579 **** if (!p_beval) return; ! if (gui_mch_get_beval_info(beval, &filename, &line, &text, &col)) { if (text && text[0]) { --- 1578,1584 ---- if (!p_beval) return; ! if (gui_mch_get_beval_info(beval, &filename, &line, &text, &col) == OK) { if (text && text[0]) { *************** *** 1622,1627 **** --- 1627,1633 ---- } } } + #endif static int *************** *** 1639,1647 **** col += ts - (col % ts); else col++; - if (col == wantedCol) - return idx + 1; idx++; } return -1; --- 1645,1653 ---- col += ts - (col % ts); else col++; idx++; + if (col >= wantedCol) + return idx; } return -1; *** ../vim61.365/src/version.c Mon Mar 3 20:17:02 2003 --- src/version.c Sat Mar 8 17:23:24 2003 *************** *** 357,360 **** --- 357,365 ---- "-multi_lang", #endif + #ifdef FEAT_NETBEANS_INTG + "+netbeans_intg", + #else + "-netbeans_intg", + #endif #ifdef FEAT_GUI_W32 # ifdef FEAT_OLE *************** *** 608,609 **** --- 612,615 ---- { /* Add new patch number below this line */ + /**/ + 366, /**/ -- For society, it's probably a good thing that engineers value function over appearance. For example, you wouldn't want engineers to build nuclear power plants that only _look_ like they would keep all the radiation inside. (Scott Adams - The Dilbert principle) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///