;; rvb-mode.el --- A mode for editing RhinoScript. ;; visual-basic-mode.el --- A mode for editing Visual Basic programs. ;; Copyright (C) 1996, Fred White ;; Author: Fred White ;; Version: 1.3 (May 1, 1996) ;; Keywords: languages basic ;; Edited by sugi ;; (autoload 'rvb-mode "rvb-mode" t) ;; (setq auto-mode-alist ;; (append (list (cons "\\.rvb$" 'rvb-mode)) auto-mode-alist)) ;; (add-hook 'rvb-mode-hook ;; (function (lambda () (abbrev-mode 1)))) (provide 'rvb-mode) (defvar vb-xemacs-p (string-match "XEmacs\\|Lucid" (emacs-version))) (defvar vb-winemacs-p (string-match "Win-Emacs" (emacs-version))) (defvar vb-win32-p (eq window-system 'win32)) ;; Variables you may want to customize. (defvar rvb-mode-indent 2 "*Default indentation per nesting level") (defvar vb-fontify-p t "*Whether to fontify Basic buffers.") (defvar vb-capitalize-keywords-p t "*Whether to capitalize BASIC keywords.") (defvar vb-wild-files "*.frm *.bas *.cls" "*Wildcard pattern for BASIC source files") (defvar vb-ide-pathname nil "*The full pathname of your Visual Basic exe file, if any.") (defvar vb-defn-templates (list "Public Sub ()\nEnd Sub\n\n" "Public Function () As Variant\nEnd Function\n\n" "Public Property Get ()\nEnd Property\n\n") "*List of function templates though which vb-new-sub cycles.") (defvar rvb-mode-syntax-table nil) (if rvb-mode-syntax-table () (setq rvb-mode-syntax-table (make-syntax-table)) (modify-syntax-entry ?\' "\<" rvb-mode-syntax-table) ; Comment starter (modify-syntax-entry ?\n ">" rvb-mode-syntax-table) (modify-syntax-entry ?\\ "w" rvb-mode-syntax-table) (modify-syntax-entry ?_ "w" rvb-mode-syntax-table)) (defvar rvb-mode-map nil) (if rvb-mode-map () (setq rvb-mode-map (make-sparse-keymap)) (define-key rvb-mode-map "\t" 'vb-indent-line) (define-key rvb-mode-map "\r" 'vb-newline-and-indent) (define-key rvb-mode-map "\M-\C-a" 'vb-beginning-of-defun) (define-key rvb-mode-map "\M-\C-e" 'vb-end-of-defun) (define-key rvb-mode-map "\M-\C-h" 'vb-mark-defun) (define-key rvb-mode-map "\M-\C-\\" 'vb-indent-region) (define-key rvb-mode-map "\M-q" 'vb-fill-or-indent) (cond (vb-winemacs-p (define-key rvb-mode-map '(control C) 'vb-start-ide)) (vb-win32-p (define-key rvb-mode-map (read "[?\\S-\\C-c]") 'vb-start-ide))) (if vb-xemacs-p (progn (define-key rvb-mode-map "\M-G" 'vb-grep) (define-key rvb-mode-map '(meta backspace) 'backward-kill-word) (define-key rvb-mode-map '(control meta /) 'vb-new-sub)))) ;; These abbrevs are valid only in a code context. (defvar rvb-mode-abbrev-table nil) (defvar rvb-mode-hook ()) ;; Is there a way to case-fold all regexp matches? (defconst vb-defun-start-regexp (concat "^[ \t]*\\([Pp]ublic \\|[Pp]rivate \\|[Ss]tatic \\)*" "\\([Ss]ub\\|[Ff]unction\\|[Pp]roperty +[GgSsLl]et\\|[Tt]ype\\)" "[ \t]+\\(\\w+\\)[ \t]*(?")) (defconst vb-defun-end-regexp "^[ \t]*[Ee]nd \\([Ss]ub\\|[Ff]unction\\|[Pp]roperty\\|[Tt]ype\\)") ;; Includes the compile-time #if variation. (defconst vb-if-regexp "^[ \t]*#?[Ii]f") (defconst vb-else-regexp "^[ \t]*#?[Ee]lse\\([Ii]f\\)?") (defconst vb-endif-regexp "[ \t]*#?[Ee]nd[ \t]*[Ii]f") (defconst vb-continuation-regexp "^.*\\_[ \t]*$") (defconst vb-label-regexp "^[ \t]*[a-zA-Z0-9_]+:$") (defconst vb-select-regexp "^[ \t]*[Ss]elect[ \t]+[Cc]ase") (defconst vb-case-regexp "^[ \t]*[Cc]ase") (defconst vb-select-end-regexp "^[ \t]*[Ee]nd[ \t]+[Ss]elect") (defconst vb-for-regexp "^[ \t]*[Ff]or\\b") (defconst vb-next-regexp "^[ \t]*[Nn]ext\\b") (defconst vb-do-regexp "^[ \t]*[Dd]o\\b") (defconst vb-loop-regexp "^[ \t]*[Ll]oop\\b") (defconst vb-while-regexp "^[ \t]*[Ww]hile\\b") (defconst vb-wend-regexp "^[ \t]*[Ww]end\\b") (defconst vb-with-regexp "^[ \t]*[Ww]ith\\b") (defconst vb-end-with-regexp "^[ \t]*[Ee]nd[ \t]+[Ww]ith\\b") (defconst vb-blank-regexp "^[ \t]*$") (defconst vb-comment-regexp "^[ \t]*\\s<.*$") ;; This is some approximation of the set of reserved words in Visual Basic. (defconst vb-all-keywords '("Aggregate" "And" "App" "AppActivate" "Application" "Array" "As" "Asc" "AscB" "Atn" "Beep" "BeginTrans" "Boolean" "ByVal" "CBool" "CByte" "CCur" "CDate" "CDbl" "CInt" "CLng" "CSng" "CStr" "CVErr" "CVar" "Call" "Case" "ChDir" "ChDrive" "Character" "Choose" "Chr" "ChrB" "ClassModule" "Clipboard" "Close" "Collection" "Column" "Columns" "Command" "CommitTrans" "CompactDatabase" "Component" "Components" "Const" "Container" "Containers" "Cos" "CreateDatabase" "CreateObject" "CurDir" "Currency" "DBEngine" "DDB" "Data" "Database" "Databases" "Date" "DateAdd" "DateDiff" "DatePart" "DateSerial" "DateValue" "Day" "Debug" "Declare" "Deftype" "DeleteSetting" "Dim" "Dir" "Do" "Domain" "Double" "Dynaset" "EOF" "Each" "Else" "End" "Environ" "Erase" "Err" "Error" "Exit" "Exp" "FV" "False" "Field" "Fields" "FileAttr" "FileCopy" "FileDateTime" "FileLen" "Fix" "Font" "For" "Form" "FormTemplate" "Format" "Forms" "FreeFile" "FreeLocks" "Function" "Get" "GetAllSettings" "GetAttr" "GetObject" "GetSetting" "GoSub" "GoTo" "Group" "Groups" "Hex" "Hour" "IIf" "IMEStatus" "IPmt" "IRR" "If" "InStr" "Input" "Int" "Integer" "Is" "IsArray" "IsDate" "IsEmpty" "IsError" "IsMissing" "IsNull" "IsNumeric" "IsObject" "Kill" "LBound" "LCase" "LOF" "LSet" "LTrim" "Left" "Len" "Let" "Like" "Line" "Load" "LoadPicture" "LoadResData" "LoadResPicture" "LoadResString" "Loc" "Lock" "Log" "Long" "Loop" "MDIForm" "MIRR" "Me" "MenuItems" "MenuLine" "Mid" "Minute" "MkDir" "Month" "MsgBox" "NPV" "NPer" "Name" "New" "Next" "Now" "Oct" "On" "Open" "OpenDatabase" "Operator" "Option" "PPmt" "PV" "Parameter" "Parameters" "Partition" "Picture" "Pmt" "Print" "Printer" "Printers" "Private" "ProjectTemplate" "Properties" "Public" "Put" "QBColor" "QueryDef" "QueryDefs" "RSet" "RTrim" "Randomize" "Rate" "ReDim" "Recordset" "Recordsets" "RegisterDatabase" "Relation" "Relations" "Rem" "RepairDatabase" "Reset" "Resume" "Return" "Right" "RmDir" "Rnd" "Rollback" "RowBuffer" "SLN" "SYD" "SavePicture" "SaveSetting" "Screen" "Second" "Seek" "SelBookmarks" "Select" "SelectedComponents" "SendKeys" "Set" "SetAttr" "SetDataAccessOption" "SetDefaultWorkspace" "Sgn" "Shell" "Sin" "Single" "Snapshot" "Space" "Spc" "Sqr" "Static" "Stop" "Str" "StrComp" "StrConv" "String" "Sub" "SubMenu" "Switch" "Tab" "Table" "TableDef" "TableDefs" "Tan" "Then" "Time" "TimeSerial" "TimeValue" "Timer" "To" "Trim" "True" "Type" "TypeName" "UBound" "UCase" "Unload" "Unlock" "Val" "VarType" "Verb" "Weekday" "Wend" "While" "Width" "With" "Workspace" "Workspaces" "Write" "Year" "End If" "ElseIf" "Rhino" "Preserve" "AddArc3Pt" "AddBox" "AddCircle" "AddCircle3Pt" "AddCone" "AddCurve" "AddCylinder" "AddDimStyle" "AddDirectionalLight" "AddEdgeSrf" "AddFilletCurve" "AddGroup" "AddInerpCrvOnSrf" "AddInterpCurve" "AddInterpCurveEx" "AddLayer" "AddLine" "AddLinearLight" "AddLoftSrf" "AddMaterialToLayer" "AddMaterialToObject" "AddMesh" "AddNamedCPlane" "AddNamedView" "AddNurbsCurve" "AddNurbsSurface" "AddObjectsToGroup" "AddObjectToGroup" "AddPlanarSrf" "AddPoint" "AddPointCloud" "AddPointLight" "AddPoints" "AddPolyline" "AddRailRevSrf" "AddRectangularLight" "AddRevSrf" "AddSearchPath" "AddSphere" "AddSpotLight" "AddSrfControlPtGrid" "AddSrfControlPtGrid" "AddSrfPt" "AddSrfPtGrid" "AddText" "AddTextDot" "AddToolbar" "AddToolbarButton" "AddToolbarCollection" "AddTorus" "AllObjects" "AllProcedures" "Angle" "Angle2" "annotateCurveEndPoints" "AppearanceColor" "ArcAngle" "ArcCenterPoint" "ArcMidPoint" "ArcRadius" "ArrayPointOnSurface" "AutosaveFile" "AutosaveInterval" "Block Methods" "BlockContainerCount" "BlockContainers" "BlockCount" "BlockDescription" "BlockInstanceCount" "BlockInstanceInsertPoint" "BlockInstanceName" "BlockInstances" "BlockInstanceXform" "BlockNames" "BlockObjectCount" "BlockObjects" "BlockObjects" "BlockPath" "BlockURL" "BlockURLTag" "BooleanDifference" "BooleanIntersection" "BooleanUnion" "BoundingBox" "BrepClosestPoint" "BrouseForFolder" "BuildDate" "CheckListBox" "CircleCenterPoint" "CircleCircumference" "CircleRadius" "ClearCommandHistory" "ClipboardText" "CloseCurve" "CloseToolbarCollection" "ComboListBox" "Command" "CommandHistory" "ConvertCurveToPolyline" "CopyObject" "CopyObjects" "CopyObjectsToLayer" "CreatePreviewImage" "CreateShortcut" "CullDuplicateNumbers" "CullDuplicatePoints" "CullDuplicateStrings" "CurrentDimStyle" "CurrentLayer" "CurrentModeInfo" "CurrentPrinter" "CurrentView" "Curve Methods" "CurveArrows" "CurveBrepIntersection" "CurveDegree" "CurveDim" "CurveDirectionsMatch" "CurveDiscontinuity" "CurveDomain" "CurveEditPoints" "CurveEndPoint" "CurveEvaluate" "CurveFilletPoints" "CurveFilletPoint" "CurveKnotCount" "CurveKnots" "CurveLength" "CurveMidPoint" "CurveNormal" "CurvePointCount" "CurvePoints" "CurveRadius" "CurveSeam" "CurveStartPoint" "CurveSurfaceIntersection" "CurveTangent" "CurveWeights" "DefaultRenderer" "DeleteBlock" "DeleteDimStyle" "DeleteDocumentData" "DeleteGroup" "DeleteLayer" "DeleteNamedCPlane" "DeleteNamedView" "DeleteObject" "DeleteObjectData" "DeleteObjects" "DeleteSearchPath" "DeleteToolbar" "Dimension Methods" "DimentionText" "DimensionUserText" "DimensionValue" "DimScale" "DimStyleAnglePrecision" "DimStyleArrowSize" "DimStyleCount" "DimStyleExtension" "DimStyleFont" "DimStyleLinearPrecision" "DimStyleNames" "DimStyleNumberFormat" "DimStyleOffset" "DimStyleTextAlignment" "DimStyleTextHeight" "Distance" "DividCurve" "DividCurveLength" "Document Methods" "DocumentDataCount" "DocumentModified" "DocumentName" "DocumentPath" "DocumentURL" "DrawParametricCurve" "DumpDocumentData" "DynamicArray" "EdgeAnalysisColor" "EdgeAnalysisMode" "EditBox" "EllipseCenterPoint" "EllipseQuadPoints" "EnableAutosave" "EnableLight" "EnableObjectGrips" "EnableRedraw" "EvaluateCurve" "EvaluateSurface" "ExeFolder" "Exit" "ExplodeBlockInstance" "ExplodeCurves" "ExplodePolysurfaces" "ExportPoints" "ExtendCurve" "ExtendCurveLength" "ExtendCurvePoint" "External Access" "ExtractIsoCurve" "ExtractPreviewImage" "ExtrudeCurve" "ExtrudeCurvePoint" "ExtrudeCurveStraight" "ExtrudeSurface" "FindFile" "FirstObject" "FormatMessage" "Geometry Methods" "GetAngle" "GetArrayDim" "GetBox" "GetColor" "GetCurveObject" "GetDistance" "GetDocumentData" "GetInteger" "GetObjectData" "GetObjectGrip" "GetObjectGrips" "GetObjects" "GetPoint" "GetPointOnCurve" "GetPointOnMesh" "GetPointOnSurface" "GetPoints" "GetReal" "GetRectangle" "GetSetting" "GetString" "GetSurfaceObject" "Group Methods" "GroupCount" "GroupNames" "Help" "HiddenObjects" "HideObject" "HideObjects" "HideToolBar" "HtmlBox" "ImportCurveFromExcel" "InCommand" "InsertCurveKnot" "InsetrSurfaceKnot" "InstallFolder" "IntegerBox" "IntersectBreps" "Introduction" "InvertSelectedObjects" "IsAlignedDimension" "IsAngularDimension" "IsArc" "IsBlock" "IsBlockEmbedded" "IsBlockInstance" "IsBlockInUse" "IsBlockReference" "IsBrep" "IsCircle" "IsCommand" "IsCurve" "IsCurveClosed" "IsCurveInPlane" "IsCurveLinear" "IsCurvePeridic" "IsCurvePlanar" "IsCurveRational" "IsDiameterDimension" "IsDimension" "IsDimStyle" "IsDimStyleRefernce" "IsDirectionalLight" "IsDocumentData" "IsDocumentModified" "IsEllipse" "IsGroup" "IsGroupEmpty" "IsLayer" "IsLayerChangeable" "IsLayerEmpty" "IsLayerLocked" "IsLayerOn" "IsLayerReference" "IsLayerSelectable" "IsLayerVisible" "IsLeader" "IsLight" "IsLightEnable" "IsLightReference" "IsLine" "IsLinearDimension" "IsLinearLight" "IsMaterialDecault" "IsMaterialReference" "IsMesh" "IsMeshClosed" "IsObject" "IsObjectData" "IsObjectHidden" "IsObjectInGroup" "IsObjectLocked" "IsObjectNormal" "IsObjectReference" "IsObjectSelectable" "IsObjectSelected" "IsObjectSolid" "IsObjectValid" "IsPoint" "IsPointCloud" "IsPointInSurface" "IsPointLight" "IsPointOnCurve" "IsPointOnSurface" "IsPolyCurve" "IsPolyline" "IsPolysurface" "IsPolysurfaceClosed" "IsPolysurfacePlaner" "IsProcedure" "IsRadialDimension" "IsRectangularLight" "IsSpotLight" "IsSurface" "IsSurfaceClosed" "IsSurfacePeriodic" "IsSurfacePlanar" "IsSurfaceRational" "IsSurfaceSingular" "IsSurfaceTrimmed" "IsText" "IsTextDot" "IsToolbar" "IsToolbarCollection" "IsToolBarVisible" "IsView" "IsViewCurrent" "IsViewMaximized" "IsViewPerspective" "IsViewTitleVisible" "JoinArrays" "JoinCurves" "JoinSurfaces" "LastCommandName" "LastCommandResult" "LastCreatedObjects" "LastLoadedScriptFile" "LastObject" "Layer Methods" "LayerColor" "LayerCount" "LayerMaterialIndex" "LayerMode" "LayerOrder" "Light Methods" "LightColor" "LightCount" "LightDirection" "LightLocation" "LightName" "LightObjects" "ListBox" "LocaleID" "LockedObjects" "LockObject" "LockObjects" "MakeCurvePeriodic" "MakeNurbsCurve" "MakeSurfacePeriodic" "MatchMaterial" "Material Methods" "MaterialBump" "MaterialColor" "MaterialName" "MaterialReflectiveColor" "MaterialShine" "MaterialTexture" "MaterialTransparency" "MaximizeRestoreView" "MeshArea" "MeshAreaCentroid" "MeshContourPoints" "MeshFaceCenters" "MeshFaceNormals" "MeshFaces" "MeshFaceVertices" "MeshNakedEdgePoints" "MeshPolyline" "MeshQuadCount" "MeshQuadsToTriangles" "MeshTextureCoordinates" "MeshTruangleCount" "MeshVertexCount" "MeshVertexNormals" "MeshVertices" "MeshVolume" "MeshVolumeCentroid" "MessageBeep" "MessageBox" "Methods" "MirrorObject" "MirrorObjects" "MultiListBox" "NamedCPlane" "NamedCPlanes" "NamedViews" "NextObject" "NextObjectGrip" "NormalObjects" "Notes" "Object Grip Methods" "Object Methods" "ObjectColor" "ObjectColorSource" "ObjectDataCount" "ObjectDescription" "ObjectGripCount" "ObjectGripLocation" "ObjectGripLocations" "ObjectGripsOn" "ObjectGripsSelected" "ObjectGroups" "ObjectLayer" "ObjectMaterialIndex" "ObjectMaterialSource" "ObjectName" "ObjectsByColor" "ObjectsByGroup" "ObjectsByLayer" "ObjectsByName" "ObjectsByType" "ObjectsByURL" "ObjectTopGroup" "ObjectType" "ObjectURL" "OpenFileName" "OpenToolbarCollection" "OrientObject" "OrientObjects" "Ortho" "Osnap" "OsnapDialog" "OsnapMode" "Planar" "PlanarClosedCurveContainment" "PlanarCurveCollision" "PlugIns" "PointCloudCount" "PointCloudPoints" "PointCoordinates" "PointInPlanarClosedCurve" "PointsAreCoplanar" "PolyCurveCount" "PolylineVertices" "PopupMenu" "PrevObjectGrip" "Print" "PrinterNames" "PrintEx" "ProjectOsnaps" "Prompt" "PropertyListBox" "Pt2Str" "PullCurve" "PurgeLayer" "ReadTextFile" "RealBox" "Redraw" "ReferenceObjects" "RegistryKey" "RemoveObjectFromAllGroups" "RemoveObjectFromGroup" "RemoveObjectFromTopGroup" "RemoveObjectsFromGroup" "RenameBlock" "ReNameDimStyle" "RenameGroup" "RenameLayer" "RenameView" "RenderAntialias" "RenderColor" "RenderResoluton" "RenderSettings" "RestoreNamedCPlane" "RestoreNamedView" "ReverseCurve" "RGB Helpers" "RingTorus" "RotateCamera" "RotateObject" "RotateObjects" "SaveFileName" "SaveSetteings" "SaveToolbarCollection" "SaveToolbarCollectionAs" "SaveView" "ScaleObject" "ScaleObjects" "ScreenSize" "SdkVersion" "SearchPathCount" "SearchPathList" "SelectedObjectGrips" "SelectedObjects" "Selection Methods" "SelectObject" "SelectObjectGrip" "SelectObjectGrips" "SelectObjectGrips" "SelectObjects" "SendKeystrokes" "SetDocumentData" "SetObjectData" "ShearObject" "ShearObjects" "ShowObject" "ShowObjects" "ShowToolBar" "ShowViewTitle" "SimplifyCurve" "Sleep" "Snap" "Sort" "SortNumbers" "SortPoints" "SplitCurve" "SpoolToPrinter" "SpotLightHardness" "SpotLightRadius" "SpotLightShadowIntensity" "StatusBarDistance" "StatsBarMessage" "StatusBarNumber" "StatusBarPoint" "Str2Pt" "Str2PtArray" "StringBox" "Strtok" "Surface Methods" "SurfaceArea" "SurfaceAreaCentroid" "SurfaceAreaMoments" "SurfaceClosestPoint" "SurfaceContourPoints" "SurfaceCuvature" "SurfaceDegree" "SurfaceDomain" "SurfaceEditPoints" "SurfaceEvaluate" "SurfaceIsocurveDensity" "SurfaceKnotCount" "SurfaceKnots" "SurfaceNormal" "SurfacePointCount" "SurfacePoints" "SurfaceSurfaceIntersection" "SurfaceVolume" "SurfaceVolumeCentroid" "SurfaceVolumeMoments" "SurfaceWeights" "SynchronizeCPlanes" "TemplateFile" "TemplateFolder" "TextDotPoint" "TextObjectFont" "TextObjectHeight" "TextObjectPlane" "TextObjectPoint" "TextObjectStyle" "TextObjectText" "TiltView" "ToolbarCollectionCount" "ToolbarCollectionNames" "ToolbarCollectionPath" "ToolbarCount" "ToolbarNames" "TransformObject" "TranceformObjects" "TrimCurve" "UnitAbsoluteTolerance" "UnitAngleTolerance" "UnitCustomUnitSystem" "UnitDistanceDisplayMode" "UnitDistanceDisplayPrecision" "UnitRelativeTorerance" "UnitSystem" "UnitSystemname" "UnlockObject" "UnlockObjects" "UnselectAllObjects" "UnselectedObjects" "UnselectObject" "UnselectObjectGrip" "UnselectObjectGrips" "UnselectObjects" "User Data Methods" "User Interface Methods" "Utility Methods" "Version" "View Methods" "ViewCamera" "ViewCameraLens" "ViewCameraTarget" "ViewCameraUp" "ViewCplane" "ViewDisplayMode" "ViewNames" "ViewProjection" "ViewSize" "ViewTarget" "Wallpaper" "WallpaperGrayScale" "WallpaperHidden""WindowHandle" "WorkingFolder" "XformCPlaneToWorld" "XformScreenToWorld" "XformWorldToCPlane" "XformWorldToScreen" "ZoomBoundingBox" "ZoomExtents" "ZoomSelected" )) (defconst vb-font-lock-keywords (list ;; Function names. '("^[ \t]*\\(function\\)\\>[ \t]*\\(\\sw+\\)?" (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)) (cons "\\([oO]n [Ee]rror [Rr]esume [Nn]ext\\)" 'font-lock-variable-name-face) (cons "\\(\\b[Ff]unction\\b\\|[eE]nd [Ff]unction\\|\\b[Ss]ub\\b\\|[Ee]nd [Ss]ub\\)" 'font-lock-type-face) (cons "\\(\\b[Ff]or\\b\\|\\b[Ee]ach\\b\\|\\b[Dd]o\\b\\|\\b[Ll]oop\\b\\|\\b[Ee]xit\\b\\|\\b[Nn]ext\\b\\)" 'font-lock-keyword-face) (cons "\\(\\b[Ii]f\\b\\|\\b[eE]lse\\b\\|\\b[Ee]lse[Ii]f\\b\\|[Ee]nd [Ii]f\\|\\b[Tt]hen\\b\\)" 'font-lock-function-name-face) (cons "\\(Rhino\\b\\)" 'font-lock-warning-face) (cons "\\(\\b[Dd]im\\b\\|\\b[Rr]e[Dd]im\\b\\|\\b[Pp]reserve\\b\\)" 'font-lock-string-face) ; (cons "\\^[ \t]\\*\\$" (cons "\\([ ]\\)" ; (cons "\\([ ]fff\\)" "^.*\\_[ \t]*$" 'font-lock-comment-face))) (set-face-foreground 'font-lock-string-face "medium purple") (set-face-foreground 'font-lock-comment-face "gray50") (defun vb-word-list-regexp (keys) (let ((re "\\b\\(") (key nil)) (while keys (setq key (car keys) keys (cdr keys)) (setq re (concat re key (if keys "\\|" "")))) (concat re "\\)\\b"))) (defun vb-keywords-to-highlight () (if (eq vb-keywords-to-highlight t) vb-all-keywords vb-keywords-to-highlight)) (put 'rvb-mode 'font-lock-keywords 'vb-font-lock-keywords) (defun rvb-mode () "A mode for editing Microsoft Visual Basic programs. Features automatic indentation, font locking, keyword capitalization, and some minor convenience functions. Commands: \\{rvb-mode-map}" (interactive) (kill-all-local-variables) (use-local-map rvb-mode-map) (setq major-mode 'rvb-mode) (setq mode-name "RhinoScript") (set-syntax-table rvb-mode-syntax-table) (add-hook 'write-file-hooks 'vb-untabify) (setq local-abbrev-table rvb-mode-abbrev-table) (if vb-capitalize-keywords-p (progn (make-local-variable 'pre-abbrev-expand-hook) (add-hook 'pre-abbrev-expand-hook 'vb-pre-abbrev-expand-hook) (abbrev-mode 1))) (make-local-variable 'comment-start) (setq comment-start "' ") (make-local-variable 'comment-start-skip) (setq comment-start-skip "'+ *") (make-local-variable 'comment-column) (setq comment-column 40) (make-local-variable 'comment-end) (setq comment-end "") (make-local-variable 'indent-line-function) (setq indent-line-function 'vb-indent-line) (if vb-fontify-p (vb-enable-font-lock)) (run-hooks 'rvb-mode-hook)) (defun vb-enable-font-lock () ;; Emacs 19.29 requires a window-system else font-lock-mode errs out. (cond ((or vb-xemacs-p window-system) ;; In win-emacs this sets font-lock-keywords back to nil! (if vb-winemacs-p (font-lock-mode 1)) ;; Accomodate emacs 19.29+ ;; From: Simon Marshall (cond ((boundp 'font-lock-defaults) (make-local-variable 'font-lock-defaults) (setq font-lock-defaults '(vb-font-lock-keywords))) (t (make-local-variable 'font-lock-keywords) (setq font-lock-keywords vb-font-lock-keywords))) (if vb-winemacs-p (font-lock-fontify-buffer) (font-lock-mode 1))))) (defun vb-construct-keyword-abbrev-table () (if rvb-mode-abbrev-table nil (let ((words vb-all-keywords) (word nil) (list nil)) (while words (setq word (car words) words (cdr words)) (setq list (cons (list (downcase word) word) list))) (define-abbrev-table 'rvb-mode-abbrev-table list)))) ;; Would like to do this at compile-time. (vb-construct-keyword-abbrev-table) (defun vb-in-code-context-p () (if (fboundp 'buffer-syntactic-context) ; XEmacs function. (null (buffer-syntactic-context)) ;; Attempt to simulate buffer-syntactic-context ;; I don't know how reliable this is. (let* ((beg (save-excursion (beginning-of-line) (point))) (list (parse-partial-sexp beg (point)))) (and (null (nth 3 list)) ; inside string. (null (nth 4 list)))))) ; inside cocmment (defun vb-pre-abbrev-expand-hook () ;; Allow our abbrevs only in a code context. (setq local-abbrev-table (if (vb-in-code-context-p) rvb-mode-abbrev-table))) (defun vb-newline-and-indent (&optional count) "Insert a newline, updating indentation." (interactive) (expand-abbrev) (save-excursion (vb-indent-line)) (call-interactively 'newline-and-indent)) (defun vb-beginning-of-defun () (interactive) (re-search-backward vb-defun-start-regexp)) (defun vb-end-of-defun () (interactive) (re-search-forward vb-defun-end-regexp)) (defun vb-mark-defun () (interactive) (beginning-of-line) (vb-end-of-defun) (set-mark (point)) (vb-beginning-of-defun) (if vb-xemacs-p (zmacs-activate-region))) (defun vb-indent-defun () (interactive) (save-excursion (vb-mark-defun) (call-interactively 'vb-indent-region))) (defun vb-fill-long-comment () "Fills block of comment lines around point." ;; Derived from code in ilisp-ext.el. (interactive) (save-excursion (beginning-of-line) (let ((comment-re "^[ \t]*\\s<+[ \t]*")) (if (looking-at comment-re) (let ((fill-prefix (buffer-substring (progn (beginning-of-line) (point)) (match-end 0)))) (while (and (not (bobp)) (looking-at vb-comment-regexp)) (forward-line -1)) (if (not (bobp)) (forward-line 1)) (let ((start (point))) ;; Make all the line prefixes the same. (while (and (not (eobp)) (looking-at comment-re)) (replace-match fill-prefix) (forward-line 1)) (if (not (eobp)) (beginning-of-line)) ;; Fill using fill-prefix (fill-region-as-paragraph start (point)))))))) (defun vb-fill-or-indent () "Fill long comment around point, if any, else indent current definition." (interactive) (cond ((save-excursion (beginning-of-line) (looking-at vb-comment-regexp)) (vb-fill-long-comment)) (t (vb-indent-defun)))) (defun vb-new-sub () "Insert template for a new subroutine. Repeat to cycle through alternatives." (interactive) (beginning-of-line) (let ((templates (cons vb-blank-regexp vb-defn-templates)) (tem nil) (bound (point))) (while templates (setq tem (car templates) templates (cdr templates)) (cond ((looking-at tem) (replace-match (or (car templates) "")) (setq templates nil)))) (search-backward "()" bound t))) (defun vb-untabify () "Do not allow any tabs into the file" (if (eq major-mode 'rvb-mode) (untabify (point-min) (point-max))) nil) (defun vb-default-tag () (if (and (not (bobp)) (save-excursion (backward-char 1) (looking-at "\\w"))) (backward-word 1)) (let ((s (point)) (e (save-excursion (forward-word 1) (point)))) (buffer-substring s e))) (defun vb-grep (tag) "Search BASIC source files in current directory for tag." (interactive (list (let* ((def (vb-default-tag)) (tag (read-string (format "Grep for [%s]: " def)))) (if (string= tag "") def tag)))) (grep (format "grep -n %s %s" tag vb-wild-files))) ;;; IDE Connection. (defun vb-buffer-project-file () "Return a guess as to the project file associated with the current buffer." (car (directory-files (file-name-directory (buffer-file-name)) t "\\.vbp"))) (defun vb-start-ide () "Start RhinoScript (or your favorite IDE, (after Emacs, of course)) on the first project file in the current directory. Note: it's not a good idea to leave RhinoScript running while you are editing in emacs, since RhinoScript has no provision for reloading changed files." (interactive) (let (file) (cond ((null vb-ide-pathname) (error "No pathname set for RhinoScript. See vb-ide-pathname")) ((null (setq file (vb-buffer-project-file))) (error "No project file found.")) ((fboundp 'win-exec) (iconify-emacs) (win-exec vb-ide-pathname 'win-show-normal file)) ((fboundp 'start-process) (iconify-frame (selected-frame)) (start-process "*VisualBasic*" nil vb-ide-pathname file)) (t (error "No way to spawn process!"))))) ;;; Indentation-related stuff. (defun vb-indent-region (start end) "Perform vb-indent-line on each line in region." (interactive "r") (save-excursion (goto-char start) (beginning-of-line) (while (and (not (eobp)) (< (point) end)) (if (not (looking-at vb-blank-regexp)) (vb-indent-line)) (forward-line 1))) (cond ((fboundp 'zmacs-deactivate-region) (zmacs-deactivate-region)) ((fboundp 'deactivate-mark) (deactivate-mark)))) (defun vb-previous-line-of-code () (if (not (bobp)) (forward-line -1)) ; previous-line depends on goal column (while (and (not (bobp)) (or (looking-at vb-blank-regexp) (looking-at vb-comment-regexp))) (forward-line -1))) (defun vb-find-original-statement () ;; If the current line is a continuation from the previous, move ;; back to the original stmt. (let ((here (point))) (vb-previous-line-of-code) (while (and (not (bobp)) (looking-at vb-continuation-regexp)) (setq here (point)) (vb-previous-line-of-code)) (goto-char here))) (defun vb-find-matching-stmt (open-regexp close-regexp) ;; Searching backwards (let ((level 0)) (while (and (>= level 0) (not (bobp))) (vb-previous-line-of-code) (vb-find-original-statement) (cond ((looking-at close-regexp) (setq level (+ level 1))) ((looking-at open-regexp) (setq level (- level 1))))))) (defun vb-find-matching-if () (vb-find-matching-stmt vb-if-regexp vb-endif-regexp)) (defun vb-find-matching-select () (vb-find-matching-stmt vb-select-regexp vb-select-end-regexp)) (defun vb-find-matching-for () (vb-find-matching-stmt vb-for-regexp vb-next-regexp)) (defun vb-find-matching-do () (vb-find-matching-stmt vb-do-regexp vb-loop-regexp)) (defun vb-find-matching-while () (vb-find-matching-stmt vb-while-regexp vb-wend-regexp)) (defun vb-find-matching-with () (vb-find-matching-stmt vb-with-regexp vb-end-with-regexp)) (defun vb-calculate-indent () (let ((original-point (point))) (save-excursion (beginning-of-line) ;; Some cases depend only on where we are now. (cond ((or (looking-at vb-defun-start-regexp) (looking-at vb-label-regexp) (looking-at vb-defun-end-regexp)) 0) ;; The outdenting stmts, which simply match their original. ((or (looking-at vb-else-regexp) (looking-at vb-endif-regexp)) (vb-find-matching-if) (current-indentation)) ;; All the other matching pairs act alike. ((looking-at vb-next-regexp) ; for/next (vb-find-matching-for) (current-indentation)) ((looking-at vb-loop-regexp) ; do/loop (vb-find-matching-do) (current-indentation)) ((looking-at vb-wend-regexp) ; while/wend (vb-find-matching-while) (current-indentation)) ((looking-at vb-end-with-regexp) ; with/end with (vb-find-matching-with) (current-indentation)) ((looking-at vb-select-end-regexp) ; select case/end select (vb-find-matching-select) (current-indentation)) ;; A case of a select is somewhat special. ((looking-at vb-case-regexp) (vb-find-matching-select) (+ (current-indentation) rvb-mode-indent)) (t ;; Other cases which depend on the previous line. (vb-previous-line-of-code) ;; Skip over label lines, which always have 0 indent. (while (looking-at vb-label-regexp) (vb-previous-line-of-code)) (cond ((looking-at vb-continuation-regexp) (vb-find-original-statement) ;; Indent continuation line under matching open paren, ;; or else one word in. (let* ((orig-stmt (point)) (matching-open-paren (condition-case () (save-excursion (goto-char original-point) (beginning-of-line) (backward-up-list 1) ;; Only if point is now w/in cont. block. (if (<= orig-stmt (point)) (current-column))) (error nil)))) (cond (matching-open-paren (1+ matching-open-paren)) (t ;; Else, after first word on original line. (back-to-indentation) (forward-word 1) (while (looking-at "[ \t]") (forward-char 1)) (current-column))))) (t (vb-find-original-statement) (let ((indent (current-indentation))) ;; All the various +indent regexps. (cond ((looking-at vb-defun-start-regexp) (+ indent rvb-mode-indent)) ((or (looking-at vb-if-regexp) (looking-at vb-else-regexp)) (+ indent rvb-mode-indent)) ((or (looking-at vb-select-regexp) (looking-at vb-case-regexp)) (+ indent rvb-mode-indent)) ((or (looking-at vb-do-regexp) (looking-at vb-for-regexp) (looking-at vb-while-regexp) (looking-at vb-with-regexp)) (+ indent rvb-mode-indent)) (t ;; By default, just copy indent from prev line. indent)))))))))) (defun vb-indent-to-column (col) (let* ((bol (save-excursion (beginning-of-line) (point))) (point-in-whitespace (<= (point) (+ bol (current-indentation)))) (blank-line-p (save-excursion (beginning-of-line) (looking-at vb-blank-regexp)))) (cond ((/= col (current-indentation)) (save-excursion (beginning-of-line) (back-to-indentation) (delete-region bol (point)) (indent-to col)))) ;; If point was in the whitespace, move back-to-indentation. (cond (blank-line-p (end-of-line)) (point-in-whitespace (back-to-indentation))))) (defun vb-indent-line () "Indent current line for BASIC" (interactive) (vb-indent-to-column (vb-calculate-indent)))