X-Git-Url: https://git.donarmstrong.com/?p=lib.git;a=blobdiff_plain;f=emacs_el%2Fgraphviz-dot-mode.el;fp=emacs_el%2Fgraphviz-dot-mode.el;h=0000000000000000000000000000000000000000;hp=ebaa1aac0868388301ce95d7b7ef8a258c1f9a1e;hb=57355d630c5b9472f9b77eddfb17886931784080;hpb=317502fdfe0ea759f0d166e615a33be59a1f7fba diff --git a/emacs_el/graphviz-dot-mode.el b/emacs_el/graphviz-dot-mode.el deleted file mode 100644 index ebaa1aa..0000000 --- a/emacs_el/graphviz-dot-mode.el +++ /dev/null @@ -1,919 +0,0 @@ -;;; graphviz-dot-mode.el --- Mode for the dot-language used by graphviz (att). - -;; Copyright (C) 2002 - 2005 Pieter Pareit - -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2 of -;; the License, or (at your option) any later version. - -;; This program is distributed in the hope that it will be -;; useful, but WITHOUT ANY WARRANTY; without even the implied -;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -;; PURPOSE. See the GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public -;; License along with this program; if not, write to the Free -;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -;; MA 02111-1307 USA - -;; Authors: Pieter Pareit -;; Rubens Ramos -;; Maintainer: Pieter Pareit -;; Homepage: http://users.skynet.be/ppareit/projects/graphviz-dot-mode/graphviz-dot-mode.html -;; Created: 28 Oct 2002 -;; Last modified: 24 Feb 2005 -;; Version: 0.3.4 -;; Keywords: mode dot dot-language dotlanguage graphviz graphs att - -;;; Commentary: -;; Use this mode for editing files in the dot-language (www.graphviz.org and -;; http://www.research.att.com/sw/tools/graphviz/). -;; -;; To use graphviz-dot-mode, add -;; (load-file "PATH_TO_FILE/graphviz-dot-mode.el") -;; to your ~/.emacs(.el) or ~/.xemacs/init.el -;; -;; The graphviz-dot-mode will do font locking, indentation, preview of graphs -;; and eases compilation/error location. There is support for both GNU Emacs -;; and XEmacs. -;; -;; Font locking is automatic, indentation uses the same commands as -;; other modes, tab, M-j and C-M-q. Insertion of comments uses the -;; same commands as other modes, M-; . You can compile a file using -;; M-x compile or C-c c, after that M-x next-error will also work. -;; There is support for viewing an generated image with C-c p. - -;;; Todo: -;; * cleanup the mess of graphviz-dot-compilation-parse-errors -;; * electric indentation is fundamentally broken, because -;; {...} are also used for record nodes. You could argue, I suppose, that -;; many diagrams don't need those, but it would be worth having a note (and -;; it makes sense that the default is now for electric indentation to be -;; off). - -;;; History: - -;; Version 0.3.4 bug fixes -;; 24/02/2005: * fixed a bug in graphviz-dot-preview -;; Version 0.3.3 bug fixes -;; 13/02/2005: Reuben Thomas -;; * add graphviz-dot-indent-width -;; Version 0.3.2 bug fixes -;; 25/03/2004: Rubens Ramos -;; * semi-colons and brackets are added when electric -;; behaviour is disabled. -;; * electric characters do not behave electrically inside -;; comments or strings. -;; * default for electric-braces is disabled now (makes more -;; sense I guess). -;; * using read-from-minibuffer instead of read-shell-command -;; for emacs. -;; * Fixed test for easymenu, so that it works on older -;; versions of XEmacs. -;; * Fixed indentation error when trying to indent last brace -;; of an empty graph. -;; * region-active-p does not exist in emacs (21.2 at least), -;; so removed from code -;; * Added uncomment menu option -;; Version 0.3.1 bug fixes -;; 03/03/2004: * backward-word needs argument for older emacs -;; Version 0.3 added features and fixed bugs -;; 10/01/2004: fixed a bug in graphviz-dot-indent-graph -;; 08/01/2004: Rubens Ramos -;; * added customization support -;; * Now it works on XEmacs and Emacs -;; * Added support to use an external Viewer -;; * Now things do not break when dot mode is entered -;; when there is no buffer name, but the side effect is -;; that in this case, the compilation command is not -;; correct. -;; * Preview works on XEmacs and emacs. -;; * Electric indentation on newline -;; * Minor changes to indentation -;; * Added keyword completion (but could be A LOT better) -;; * There are still a couple of ugly hacks. Look for 'RR'. -;; Version 0.2 added features -;; 11/11/2002: added preview support. -;; 10/11/2002: indent a graph or subgraph at once with C-M-q. -;; 08/11/2002: relaxed rules for indentation, the may now be extra chars -;; after beginning of graph (comment's for example). -;; Version 0.1.2 bug fixes and naming issues -;; 06/11/2002: renamed dot-font-lock-defaults to dot-font-lock-keywords. -;; added some documentation to dot-colors. -;; provided a much better way to handle my max-specpdl-size -;; problem. -;; added an extra autoload cookie (hope this helps, as I don't -;; yet use autoload myself) -;; Version 0.1.1 bug fixes -;; 06/11/2002: added an missing attribute, for font-locking to work. -;; fixed the regex generating, so that it only recognizes -;; whole words -;; 05/11/2002: there can now be extra white space chars after an '{'. -;; 04/11/2002: Why I use max-specpdl-size is now documented, and old value -;; gets restored. -;; Version 0.1 initial release -;; 02/11/2002: implemented parser for *compilation* of a .dot file. -;; 01/11/2002: implemented compilation of an .dot file. -;; 31/10/2002: added syntax-table to the mode. -;; 30/10/2002: implemented indentation code. -;; 29/10/2002: implemented all of font-lock. -;; 28/10/2002: derived graphviz-dot-mode from fundamental-mode, started -;; implementing font-lock. - -;;; Code: - -(defconst graphviz-dot-mode-version "0.3.3" - "Version of `graphviz-dot-mode.el'.") - -(defgroup graphviz nil - "Major mode for editing Graphviz Dot files" - :group 'tools) - -(defun graphviz-dot-customize () - "Run \\[customize-group] for the `graphviz' group." - (interactive) - (customize-group 'graphviz)) - -(defvar graphviz-dot-mode-abbrev-table nil - "Abbrev table in use in Graphviz Dot mode buffers.") -(define-abbrev-table 'graphviz-dot-mode-abbrev-table ()) - -(defcustom graphviz-dot-dot-program "dot" - "*Location of the dot program. This is used by `compile'." - :type 'string - :group 'graphviz) - -(defcustom graphviz-dot-view-command "doted %s" - "*External program to run on the buffer. You can use `%s' in this string, -and it will be substituted by the buffer name." - :type 'string - :group 'graphviz) - -(defcustom graphviz-dot-view-edit-command nil - "*Whether to allow the user to edit the command to run an external -viewer." - :type 'boolean - :group 'graphviz) - -(defcustom graphviz-dot-save-before-view t - "*If not nil, M-x graphviz-dot-view saves the current buffer before running -the command." - :type 'boolean - :group 'graphviz) - -(defcustom graphviz-dot-auto-indent-on-newline t - "*If not nil, `electric-graphviz-dot-terminate-line' is executed in a line is terminated." - :type 'boolean - :group 'graphviz) - -(defcustom graphviz-dot-indent-width default-tab-width - "*Indentation width in Graphviz Dot mode buffers." - :type 'integer - :group 'graphviz) - -(defcustom graphviz-dot-auto-indent-on-braces nil - "*If not nil, `electric-graphviz-dot-open-brace' and `electric-graphviz-dot-close-brace' are executed when { or } are typed" - :type 'boolean - :group 'graphviz) - -(defcustom graphviz-dot-auto-indent-on-semi t - "*If not nil, `electric-graphviz-dot-semi' is executed when semicolon is typed" - :type 'boolean - :group 'graphviz) - -(defcustom graphviz-dot-preview-extension "png" - "*The extension to use for the compilation and preview commands. The format -for the compilation command is -`dot -T file.dot > file.'." - :type 'string - :group 'graphviz) - -(defcustom graphviz-dot-toggle-completions nil - "*Non-nil means that repeated use of \ -\\\\[graphviz-dot-complete-word] will toggle the possible -completions in the minibuffer. Normally, when there is more than one possible -completion, a buffer will display all completions." - :type 'boolean - :group 'graphviz) - -(defcustom graphviz-dot-delete-completions nil - "*Non-nil means that the completion buffer is automatically deleted when a -key is pressed." - :type 'boolean - :group 'graphviz) - -(defcustom graphviz-dot-attr-keywords - '("graph" "digraph" "subgraph" "node" "edge" "strict" "rankdir" - "size" "page" "Damping" "Epsilon" "URL" "arrowhead" "arrowsize" - "arrowtail" "bb" "bgcolor" "bottomlabel" "center" "clusterrank" - "color" "comment" "compound" "concentrate" "constraint" "decorate" - "dim" "dir" "distortion" "fillcolor" "fixedsize" "fontcolor" - "fontname" "fontpath" "fontsize" "group" "headURL" "headlabel" - "headport" "height" "label" "labelangle" "labeldistance" "labelfloat" - "labelfontcolor" "labelfontname" "labelfontsize" "labeljust" - "labelloc" "layer" "layers" "len" "lhead" "lp" "ltail" "margin" - "maxiter" "mclimit" "minlen" "model" "nodesep" "normalize" "nslimit" - "nslimit1" "ordering" "orientation" "overlap" "pack" "pagedir" - "pencolor" "peripheries" "pin" "pos" "quantum" "rank" "ranksep" - "ratio" "rects" "regular" "remincross" "rotate" "samehead" "sametail" - "samplepoint" "searchsize" "sep" "shape" "shapefile" "showboxes" - "sides" "skew" "splines" "start" "style" "stylesheet" "tailURL" - "taillabel" "tailport" "toplabel" "vertices" "voro_margin" "weight" - "z") - "*Keywords for attribute names in a graph. This is used by the auto -completion code. The actual completion tables are built when the mode -is loaded, so changes to this are not immediately visible." - :type '(repeat (string :tag "Keyword")) - :group 'graphviz) - -(defcustom graphviz-dot-value-keywords - '("true" "false" "normal" "inv" "dot" "invdot" "odot" "invodot" - "none" "tee" "empty" "invempty" "diamond" "odiamond" "box" "obox" - "open" "crow" "halfopen" "local" "global" "none" "forward" "back" - "both" "none" "BL" "BR" "TL" "TR" "RB" "RT" "LB" "LT" ":n" ":ne" ":e" - ":se" ":s" ":sw" ":w" ":nw" "same" "min" "source" "max" "sink" "LR" - "box" "polygon" "ellipse" "circle" "point" "egg" "triangle" - "plaintext" "diamond" "trapezium" "parallelogram" "house" "hexagon" - "octagon" "doublecircle" "doubleoctagon" "tripleoctagon" "invtriangle" - "invtrapezium" "invhouse" "Mdiamond" "Msquare" "Mcircle" "record" - "Mrecord" "dashed" "dotted" "solid" "invis" "bold" "filled" - "diagonals" "rounded" ) - "*Keywords for attribute values. This is used by the auto completion -code. The actual completion tables are built when the mode is loaded, -so changes to this are not immediately visible." - :type '(repeat (string :tag "Keyword")) - :group 'graphviz) - -;;; Font-locking: -(defvar graphviz-dot-colors-list - '(aliceblue antiquewhite antiquewhite1 antiquewhite2 - antiquewhite3 antiquewhite4 aquamarine aquamarine1 - aquamarine2 aquamarine3 aquamarine4 azure azure1 - azure2 azure3 azure4 beige bisque bisque1 bisque2 - bisque3 bisque4 black blanchedalmond blue blue1 - blue2 blue3 blue4 blueviolet brown brown1 brown2 - brown3 brown4 burlywood burlywood1 burlywood2 - burlywood3 burlywood4 cadetblue cadetblue1 - cadetblue2 cadetblue3 cadetblue4 chartreuse - chartreuse1 chartreuse2 chartreuse3 chartreuse4 - chocolate chocolate1 chocolate2 chocolate3 chocolate4 - coral coral1 coral2 coral3 coral4 cornflowerblue - cornsilk cornsilk1 cornsilk2 cornsilk3 cornsilk4 - crimson cyan cyan1 cyan2 cyan3 cyan4 darkgoldenrod - darkgoldenrod1 darkgoldenrod2 darkgoldenrod3 - darkgoldenrod4 darkgreen darkkhaki darkolivegreen - darkolivegreen1 darkolivegreen2 darkolivegreen3 - darkolivegreen4 darkorange darkorange1 darkorange2 - darkorange3 darkorange4 darkorchid darkorchid1 - darkorchid2 darkorchid3 darkorchid4 darksalmon - darkseagreen darkseagreen1 darkseagreen2 - darkseagreen3 darkseagreen4 darkslateblue - darkslategray darkslategray1 darkslategray2 - darkslategray3 darkslategray4 darkslategrey - darkturquoise darkviolet deeppink deeppink1 - deeppink2 deeppink3 deeppink4 deepskyblue - deepskyblue1 deepskyblue2 deepskyblue3 deepskyblue4 - dimgray dimgrey dodgerblue dodgerblue1 dodgerblue2 - dodgerblue3 dodgerblue4 firebrick firebrick1 - firebrick2 firebrick3 firebrick4 floralwhite - forestgreen gainsboro ghostwhite gold gold1 gold2 - gold3 gold4 goldenrod goldenrod1 goldenrod2 - goldenrod3 goldenrod4 gray gray0 gray1 gray10 gray100 - gray11 gray12 gray13 gray14 gray15 gray16 gray17 - gray18 gray19 gray2 gray20 gray21 gray22 gray23 - gray24 gray25 gray26 gray27 gray28 gray29 gray3 - gray30 gray31 gray32 gray33 gray34 gray35 gray36 - gray37 gray38 gray39 gray4 gray40 gray41 gray42 - gray43 gray44 gray45 gray46 gray47 gray48 gray49 - gray5 gray50 gray51 gray52 gray53 gray54 gray55 - gray56 gray57 gray58 gray59 gray6 gray60 gray61 - gray62 gray63 gray64 gray65 gray66 gray67 gray68 - gray69 gray7 gray70 gray71 gray72 gray73 gray74 - gray75 gray76 gray77 gray78 gray79 gray8 gray80 - gray81 gray82 gray83 gray84 gray85 gray86 gray87 - gray88 gray89 gray9 gray90 gray91 gray92 gray93 - gray94 gray95 gray96 gray97 gray98 gray99 green - green1 green2 green3 green4 greenyellow grey grey0 - grey1 grey10 grey100 grey11 grey12 grey13 grey14 - grey15 grey16 grey17 grey18 grey19 grey2 grey20 - grey21 grey22 grey23 grey24 grey25 grey26 grey27 - grey28 grey29 grey3 grey30 grey31 grey32 grey33 - grey34 grey35 grey36 grey37 grey38 grey39 grey4 - grey40 grey41 grey42 grey43 grey44 grey45 grey46 - grey47 grey48 grey49 grey5 grey50 grey51 grey52 - grey53 grey54 grey55 grey56 grey57 grey58 grey59 - grey6 grey60 grey61 grey62 grey63 grey64 grey65 - grey66 grey67 grey68 grey69 grey7 grey70 grey71 - grey72 grey73 grey74 grey75 grey76 grey77 grey78 - grey79 grey8 grey80 grey81 grey82 grey83 grey84 - grey85 grey86 grey87 grey88 grey89 grey9 grey90 - grey91 grey92 grey93 grey94 grey95 grey96 grey97 - grey98 grey99 honeydew honeydew1 honeydew2 honeydew3 - honeydew4 hotpink hotpink1 hotpink2 hotpink3 hotpink4 - indianred indianred1 indianred2 indianred3 indianred4 - indigo ivory ivory1 ivory2 ivory3 ivory4 khaki khaki1 - khaki2 khaki3 khaki4 lavender lavenderblush - lavenderblush1 lavenderblush2 lavenderblush3 - lavenderblush4 lawngreen lemonchiffon lemonchiffon1 - lemonchiffon2 lemonchiffon3 lemonchiffon4 lightblue - lightblue1 lightblue2 lightblue3 lightblue4 - lightcoral lightcyan lightcyan1 lightcyan2 lightcyan3 - lightcyan4 lightgoldenrod lightgoldenrod1 - lightgoldenrod2 lightgoldenrod3 lightgoldenrod4 - lightgoldenrodyellow lightgray lightgrey lightpink - lightpink1 lightpink2 lightpink3 lightpink4 - lightsalmon lightsalmon1 lightsalmon2 lightsalmon3 - lightsalmon4 lightseagreen lightskyblue lightskyblue1 - lightskyblue2 lightskyblue3 lightskyblue4 - lightslateblue lightslategray lightslategrey - lightsteelblue lightsteelblue1 lightsteelblue2 - lightsteelblue3 lightsteelblue4 lightyellow - lightyellow1 lightyellow2 lightyellow3 lightyellow4 - limegreen linen magenta magenta1 magenta2 magenta3 - magenta4 maroon maroon1 maroon2 maroon3 maroon4 - mediumaquamarine mediumblue mediumorchid - mediumorchid1 mediumorchid2 mediumorchid3 - mediumorchid4 mediumpurple mediumpurple1 - mediumpurple2 mediumpurple3 mediumpurple4 - mediumseagreen mediumslateblue mediumspringgreen - mediumturquoise mediumvioletred midnightblue - mintcream mistyrose mistyrose1 mistyrose2 mistyrose3 - mistyrose4 moccasin navajowhite navajowhite1 - navajowhite2 navajowhite3 navajowhite4 navy navyblue - oldlace olivedrab olivedrap olivedrab1 olivedrab2 - olivedrap3 oragne palegoldenrod palegreen palegreen1 - palegreen2 palegreen3 palegreen4 paleturquoise - paleturquoise1 paleturquoise2 paleturquoise3 - paleturquoise4 palevioletred palevioletred1 - palevioletred2 palevioletred3 palevioletred4 - papayawhip peachpuff peachpuff1 peachpuff2 - peachpuff3 peachpuff4 peru pink pink1 pink2 pink3 - pink4 plum plum1 plum2 plum3 plum4 powderblue - purple purple1 purple2 purple3 purple4 red red1 red2 - red3 red4 rosybrown rosybrown1 rosybrown2 rosybrown3 - rosybrown4 royalblue royalblue1 royalblue2 royalblue3 - royalblue4 saddlebrown salmon salmon1 salmon2 salmon3 - salmon4 sandybrown seagreen seagreen1 seagreen2 - seagreen3 seagreen4 seashell seashell1 seashell2 - seashell3 seashell4 sienna sienna1 sienna2 sienna3 - sienna4 skyblue skyblue1 skyblue2 skyblue3 skyblue4 - slateblue slateblue1 slateblue2 slateblue3 slateblue4 - slategray slategray1 slategray2 slategray3 slategray4 - slategrey snow snow1 snow2 snow3 snow4 springgreen - springgreen1 springgreen2 springgreen3 springgreen4 - steelblue steelblue1 steelblue2 steelblue3 steelblue4 - tan tan1 tan2 tan3 tan4 thistle thistle1 thistle2 - thistle3 thistle4 tomato tomato1 tomato2 tomato3 - tomato4 transparent turquoise turquoise1 turquoise2 - turquoise3 turquoise4 violet violetred violetred1 - violetred2 violetred3 violetred4 wheat wheat1 wheat2 - wheat3 wheat4 white whitesmoke yellow yellow1 yellow2 - yellow3 yellow4 yellowgreen) - "Possible color constants in the dot language. -The list of constant is available at http://www.research.att.com/~erg/graphviz\ -/info/colors.html") - - -(defvar graphviz-dot-color-keywords - (mapcar 'symbol-name graphviz-dot-colors-list)) - -(defvar graphviz-attr-keywords - (mapcar '(lambda (elm) (cons elm 0)) graphviz-dot-attr-keywords)) - -(defvar graphviz-value-keywords - (mapcar '(lambda (elm) (cons elm 0)) graphviz-dot-value-keywords)) - -(defvar graphviz-color-keywords - (mapcar '(lambda (elm) (cons elm 0)) graphviz-dot-color-keywords)) - -;;; Key map -(defvar graphviz-dot-mode-map () - "Keymap used in Graphviz Dot mode.") - -(if graphviz-dot-mode-map - () - (let ((map (make-sparse-keymap))) - (define-key map "\r" 'electric-graphviz-dot-terminate-line) - (define-key map "{" 'electric-graphviz-dot-open-brace) - (define-key map "}" 'electric-graphviz-dot-close-brace) - (define-key map ";" 'electric-graphviz-dot-semi) - (define-key map "\M-\t" 'graphviz-dot-complete-word) - (define-key map "\C-\M-q" 'graphviz-dot-indent-graph) - (define-key map "\C-cp" 'graphviz-dot-preview) - (define-key map "\C-cc" 'compile) - (define-key map "\C-cv" 'graphviz-dot-view) - (define-key map "\C-c\C-c" 'comment-region) - (define-key map "\C-c\C-u" 'graphviz-dot-uncomment-region) - (setq graphviz-dot-mode-map map) - )) - -;;; Syntax table -(defvar graphviz-dot-mode-syntax-table nil - "Syntax table for `graphviz-dot-mode'.") - -(if graphviz-dot-mode-syntax-table - () - (let ((st (make-syntax-table))) - (modify-syntax-entry ?/ ". 124b" st) - (modify-syntax-entry ?* ". 23" st) - (modify-syntax-entry ?\n "> b" st) - (modify-syntax-entry ?= "." st) - (modify-syntax-entry ?_ "_" st) - (modify-syntax-entry ?- "_" st) - (modify-syntax-entry ?> "." st) - (modify-syntax-entry ?[ "(" st) - (modify-syntax-entry ?] ")" st) - (modify-syntax-entry ?\" "\"" st) - (setq graphviz-dot-mode-syntax-table st) - )) - -(defvar graphviz-dot-font-lock-keywords - `(("\\(:?di\\|sub\\)?graph \\(\\sw+\\)" - (2 font-lock-function-name-face)) - (,(regexp-opt graphviz-dot-value-keywords 'words) - . font-lock-reference-face) - ;; to build the font-locking for the colors, - ;; we need more room for max-specpdl-size, - ;; after that we take the list of symbols, - ;; convert them to a list of strings, and make - ;; an optimized regexp from them - (,(let ((max-specpdl-size (max max-specpdl-size 1200))) - (regexp-opt graphviz-dot-color-keywords)) - . font-lock-string-face) - (,(concat - (regexp-opt graphviz-dot-attr-keywords 'words) - "[ \\t\\n]*=") - ;; RR - ugly, really, but I dont know why xemacs does not work - ;; if I change the next car to "1"... - (0 font-lock-variable-name-face))) - "Keyword highlighting specification for `graphviz-dot-mode'.") - -;;;###autoload -(defun graphviz-dot-mode () - "Major mode for the dot language. \\ -TAB indents for graph lines. - -\\[graphviz-dot-indent-graph]\t- Indentaion function. -\\[graphviz-dot-preview]\t- Previews graph in a buffer. -\\[graphviz-dot-view]\t- Views graph in an external viewer. -\\[graphviz-dot-indent-line]\t- Indents current line of code. -\\[graphviz-dot-complete-word]\t- Completes the current word. -\\[electric-graphviz-dot-terminate-line]\t- Electric newline. -\\[electric-graphviz-dot-open-brace]\t- Electric open braces. -\\[electric-graphviz-dot-close-brace]\t- Electric close braces. -\\[electric-graphviz-dot-semi]\t- Electric semi colons. - -Variables specific to this mode: - - graphviz-dot-dot-program (default `dot') - Location of the dot program. - graphviz-dot-view-command (default `doted %s') - Command to run when `graphviz-dot-view' is executed. - graphviz-dot-view-edit-command (default nil) - If the user should be asked to edit the view command. - graphviz-dot-save-before-view (default t) - Automatically save current buffer berore `graphviz-dot-view'. - graphviz-dot-preview-extension (default `png') - File type to use for `graphviz-dot-preview'. - graphviz-dot-auto-indent-on-newline (default t) - Whether to run `electric-graphviz-dot-terminate-line' when - newline is entered. - graphviz-dot-auto-indent-on-braces (default t) - Whether to run `electric-graphviz-dot-open-brace' and - `electric-graphviz-dot-close-brace' when braces are - entered. - graphviz-dot-auto-indent-on-semi (default t) - Whether to run `electric-graphviz-dot-semi' when semi colon - is typed. - graphviz-dot-toggle-completions (default nil) - If completions should be displayed in the buffer instead of a - completion buffer when \\[graphviz-dot-complete-word] is - pressed repeatedly. - -This mode can be customized by running \\[graphviz-dot-customize]. - -Turning on Graphviz Dot mode calls the value of the variable -`graphviz-dot-mode-hook' with no args, if that value is non-nil." - (interactive) - (kill-all-local-variables) - (use-local-map graphviz-dot-mode-map) - (setq major-mode 'graphviz-dot-mode) - (setq mode-name "dot") - (setq local-abbrev-table graphviz-dot-mode-abbrev-table) - (set-syntax-table graphviz-dot-mode-syntax-table) - (set (make-local-variable 'indent-line-function) 'graphviz-dot-indent-line) - (set (make-local-variable 'comment-start) "//") - (set (make-local-variable 'comment-start-skip) "/\\*+ *\\|//+ *") - (set (make-local-variable 'font-lock-defaults) - '(graphviz-dot-font-lock-keywords)) - ;; RR - If user is running this in the scratch buffer, there is no - ;; buffer file name... - (if (buffer-file-name) - (set (make-local-variable 'compile-command) - (concat graphviz-dot-dot-program - " -T" graphviz-dot-preview-extension " " - buffer-file-name - " > " - (file-name-sans-extension - buffer-file-name) - "." graphviz-dot-preview-extension))) - (set (make-local-variable 'compilation-parse-errors-function) - 'graphviz-dot-compilation-parse-errors) - (if dot-menu - (easy-menu-add dot-menu)) - (run-hooks 'graphviz-dot-mode-hook) - ) - -;;;; Menu definitions - -(defvar dot-menu nil - "Menu for Graphviz Dot Mode. -This menu will get created automatically if you have the `easymenu' -package. Note that the latest X/Emacs releases contain this package.") - -(and (condition-case nil - (require 'easymenu) - (error nil)) - (easy-menu-define - dot-menu graphviz-dot-mode-map "Graphviz Mode menu" - '("Graphviz" - ["Indent Graph" graphviz-dot-indent-graph t] - ["Comment Out Region" comment-region (mark)] - ["Uncomment Region" graphviz-dot-uncomment-region (mark)] - "-" - ["Compile" compile t] - ["Preview" graphviz-dot-preview - (and (buffer-file-name) - (not (buffer-modified-p)))] - ["External Viewer" graphviz-dot-view (buffer-file-name)] - "-" - ["Customize..." graphviz-dot-customize t] - ))) - -;;;; Compilation - -;; note on graphviz-dot-compilation-parse-errors: -;; It would nicer if we could just use compilation-error-regexp-alist -;; to do that, 3 options: -;; - still write dot-compilation-parse-errors, don't build -;; a return list, but modify the *compilation* buffer -;; in a way compilation-error-regexp-alist recognizes the -;; format. -;; to do that, I should globally change compilation-parse-function -;; to this function, and call the old value of comp..-parse-fun.. -;; to provide the return value. -;; two drawbacks are that, every compilation would be run through -;; this function (performance) and that in autoload there would -;; be a chance that this function would not yet be known. -;; - let the compilation run through a filter that would -;; modify the output of dot or neato: -;; dot -Tpng input.dot | filter -;; drawback: ugly, extra work for user, extra decency ... -;; no-option -;; - modify dot and neato !!! (PP:15/02/2005 seems to have happend, -;; so version 0.4.0 should clean this mess up!) -(defun graphviz-dot-compilation-parse-errors (limit-search find-at-least) - "Parse the current buffer for dot errors. -See variable `compilation-parse-errors-functions' for interface." - (interactive) - (save-excursion - (set-buffer "*compilation*") - (goto-char (point-min)) - (setq compilation-error-list nil) - (let (buffer-of-error) - (while (not (eobp)) - (cond - ((looking-at "^dot\\( -[^ ]+\\)* \\(.*\\)") - (setq buffer-of-error (find-file-noselect - (buffer-substring-no-properties - (nth 4 (match-data t)) - (nth 5 (match-data t)))))) - ((looking-at ".*:.*line \\([0-9]+\\)") - (let ((line-of-error - (string-to-number (buffer-substring-no-properties - (nth 2 (match-data t)) - (nth 3 (match-data t)))))) - (setq compilation-error-list - (cons - (cons - (point-marker) - (save-excursion - (set-buffer buffer-of-error) - (goto-line line-of-error) - (beginning-of-line) - (point-marker))) - compilation-error-list)))) - (t t)) - (forward-line 1)) ))) - -;;;; -;;;; Indentation -;;;; -(defun graphviz-dot-uncomment-region (begin end) - "Uncomments a region of code." - (interactive "r") - (comment-region begin end '(4))) - -(defun graphviz-dot-indent-line () - "Indent current line of dot code." - (interactive) - (if (bolp) - (graphviz-dot-real-indent-line) - (save-excursion - (graphviz-dot-real-indent-line)))) - -(defun graphviz-dot-real-indent-line () - "Indent current line of dot code." - (beginning-of-line) - (cond - ((bobp) - ;; simple case, indent to 0 - (indent-line-to 0)) - ((looking-at "^[ \t]*}[ \t]*$") - ;; block closing, deindent relative to previous line - (indent-line-to (save-excursion - (forward-line -1) - (max 0 (- (current-indentation) graphviz-dot-indent-width))))) - ;; other cases need to look at previous lines - (t - (indent-line-to (save-excursion - (forward-line -1) - (cond - ((looking-at "\\(^.*{[^}]*$\\)") - ;; previous line opened a block - ;; indent to that line - (+ (current-indentation) graphviz-dot-indent-width)) - ((and (not (looking-at ".*\\[.*\\].*")) - (looking-at ".*\\[.*")) ; TODO:PP : can be 1 regex - ;; previous line started filling - ;; attributes, intend to that start - (search-forward "[") - (current-column)) - ((and (not (looking-at ".*\\[.*\\].*")) - (looking-at ".*\\].*")) ; TODO:PP : " - ;; previous line stopped filling - ;; attributes, find the line that started - ;; filling them and indent to that line - (while (or (looking-at ".*\\[.*\\].*") - (not (looking-at ".*\\[.*"))) ; TODO:PP : " - (forward-line -1)) - (current-indentation)) - (t - ;; default case, indent the - ;; same as previous line - (current-indentation)) ))) ))) - -(defun graphviz-dot-indent-graph () - "Indent the graph/digraph/subgraph where point is at. -This will first teach the beginning of the graph were point is at, and -then indent this and each subgraph in it." - (interactive) - (save-excursion - ;; position point at start of graph - (while (not (or (looking-at "\\(^.*{[^}]*$\\)") (bobp))) - (forward-line -1)) - ;; bracket { one +; bracket } one - - (let ((bracket-count 0)) - (while - (progn - (cond - ;; update bracket-count - ((looking-at "\\(^.*{[^}]*$\\)") - (setq bracket-count (+ bracket-count 1))) - ;; update bracket-count - ((looking-at "^[ \t]*}[ \t]*$") - (setq bracket-count (- bracket-count 1)))) - ;; indent this line and move on - (graphviz-dot-indent-line) - (forward-line 1) - ;; as long as we are not completed or at end of buffer - (and (> bracket-count 0) (not (eobp)))))))) - -;;;; -;;;; Electric indentation -;;;; -(defun graphviz-dot-comment-or-string-p () - (let ((state (parse-partial-sexp (point-min) (point)))) - (or (nth 4 state) (nth 3 state)))) - -(defun graphviz-dot-newline-and-indent () - (save-excursion - (beginning-of-line) - (skip-chars-forward " \t") - (graphviz-dot-indent-line)) - (delete-horizontal-space) - (newline) - (graphviz-dot-indent-line)) - -(defun electric-graphviz-dot-terminate-line () - "Terminate line and indent next line." - (interactive) - (if graphviz-dot-auto-indent-on-newline - (graphviz-dot-newline-and-indent) - (newline))) - -(defun electric-graphviz-dot-open-brace () - "Terminate line and indent next line." - (interactive) - (insert "{") - (if (and graphviz-dot-auto-indent-on-braces - (not (graphviz-dot-comment-or-string-p))) - (graphviz-dot-newline-and-indent))) - -(defun electric-graphviz-dot-close-brace () - "Terminate line and indent next line." - (interactive) - (insert "}") - (if (and graphviz-dot-auto-indent-on-braces - (not (graphviz-dot-comment-or-string-p))) - (progn - (save-excursion - (beginning-of-line) - (skip-chars-forward " \t") - (graphviz-dot-indent-line)) - (newline) - (graphviz-dot-indent-line)))) - -(defun electric-graphviz-dot-semi () - "Terminate line and indent next line." - (interactive) - (insert ";") - (if (and graphviz-dot-auto-indent-on-semi - (not (graphviz-dot-comment-or-string-p))) - (graphviz-dot-newline-and-indent))) - -;;;; -;;;; Preview -;;;; -(defun graphviz-dot-preview () - "Shows an example of the current dot file in an emacs buffer. -This assumes that we are running GNU Emacs or XEmacs under a windowing system. -See `image-file-name-extensions' for customizing the files that can be -loaded in GNU Emacs, and `image-formats-alist' for XEmacs." - (interactive) - ;; unsafe to compile ourself, ask it to the user - (if (buffer-modified-p) - (message "Buffer needs to be compiled.") - (if (string-match "XEmacs" emacs-version) - ;; things are easier in XEmacs... - (find-file-other-window (concat (file-name-sans-extension - buffer-file-name) - "." graphviz-dot-preview-extension)) - ;; run through all the extensions for images - (let ((l image-file-name-extensions)) - (while - (let ((f (concat (file-name-sans-extension (buffer-file-name)) - "." - (car l)))) - ;; see if a file matches, might be best also to check - ;; if file is up to date TODO:PP - (if (file-exists-p f) - (progn (auto-image-file-mode 1) - ;; OK, this is ugly, I would need to - ;; know how I can reload a file in an existing buffer - (if (get-buffer "*preview*") - (kill-buffer "*preview*")) - (set-buffer (find-file-noselect f)) - (rename-buffer "*preview*") - (display-buffer (get-buffer "*preview*")) - ;; stop iterating - '()) - ;; will stop iterating when l is nil - (setq l (cdr l))))) - ;; each extension tested and nothing found, let user know - (when (eq l '()) - (message "No image found.")))))) - -;;;; -;;;; View -;;;; -(defun graphviz-dot-view () - "Runs an external viewer. This creates an external process every time it -is executed. If `graphviz-dot-save-before-view' is set, the current -buffer is saved before the command is executed." - (interactive) - (let ((cmd (if graphviz-dot-view-edit-command - (if (string-match "XEmacs" emacs-version) - (read-shell-command "View command: " - (format graphviz-dot-view-command - (buffer-file-name))) - (read-from-minibuffer "View command: " - (format graphviz-dot-view-command - (buffer-file-name)))) - (format graphviz-dot-view-command (buffer-file-name))))) - (if graphviz-dot-save-before-view - (save-buffer)) - (setq novaproc (start-process-shell-command - (downcase mode-name) nil cmd)) - (message (format "Executing `%s'..." cmd)))) - -;;;; -;;;; Completion -;;;; -(defvar graphviz-dot-str nil) -(defvar graphviz-dot-all nil) -(defvar graphviz-dot-pred nil) -(defvar graphviz-dot-buffer-to-use nil) -(defvar graphviz-dot-flag nil) - -(defun graphviz-dot-get-state () - "Returns the syntax state of the current point." - (let ((state (parse-partial-sexp (point-min) (point)))) - (cond - ((nth 4 state) 'comment) - ((nth 3 state) 'string) - ((not (nth 1 state)) 'out) - (t (save-excursion - (skip-chars-backward "^[,=\\[]{};") - (backward-char) - (cond - ((looking-at "[\\[,]{};") 'attribute) - ((looking-at "=") (progn - (backward-word 1) - (if (looking-at "[a-zA-Z]*color") - 'color - 'value))) - (t 'other))))))) - -(defun graphviz-dot-get-keywords () - "Return possible completions for a word" - (let ((state (graphviz-dot-get-state))) - (cond - ((equal state 'comment) ()) - ((equal state 'string) ()) - ((equal state 'out) graphviz-attr-keywords) - ((equal state 'value) graphviz-value-keywords) - ((equal state 'color) graphviz-color-keywords) - ((equal state 'attribute) graphviz-attr-keywords) - (t graphviz-attr-keywords)))) - -(defvar graphviz-dot-last-word-numb 0) -(defvar graphviz-dot-last-word-shown nil) -(defvar graphviz-dot-last-completions nil) - -(defun graphviz-dot-complete-word () - "Complete word at current point." - (interactive) - (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point))) - (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point))) - (graphviz-dot-str (buffer-substring b e)) - (allcomp (if (and graphviz-dot-toggle-completions - (string= graphviz-dot-last-word-shown - graphviz-dot-str)) - graphviz-dot-last-completions - (all-completions graphviz-dot-str - (graphviz-dot-get-keywords)))) - (match (if graphviz-dot-toggle-completions - "" (try-completion - graphviz-dot-str (mapcar '(lambda (elm) - (cons elm 0)) allcomp))))) - ;; Delete old string - (delete-region b e) - - ;; Toggle-completions inserts whole labels - (if graphviz-dot-toggle-completions - (progn - ;; Update entry number in list - (setq graphviz-dot-last-completions allcomp - graphviz-dot-last-word-numb - (if (>= graphviz-dot-last-word-numb (1- (length allcomp))) - 0 - (1+ graphviz-dot-last-word-numb))) - (setq graphviz-dot-last-word-shown - (elt allcomp graphviz-dot-last-word-numb)) - ;; Display next match or same string if no match was found - (if (not (null allcomp)) - (insert "" graphviz-dot-last-word-shown) - (insert "" graphviz-dot-str) - (message "(No match)"))) - ;; The other form of completion does not necessarily do that. - - ;; Insert match if found, or the original string if no match - (if (or (null match) (equal match 't)) - (progn (insert "" graphviz-dot-str) - (message "(No match)")) - (insert "" match)) - ;; Give message about current status of completion - (cond ((equal match 't) - (if (not (null (cdr allcomp))) - (message "(Complete but not unique)") - (message "(Sole completion)"))) - ;; Display buffer if the current completion didn't help - ;; on completing the label. - ((and (not (null (cdr allcomp))) (= (length graphviz-dot-str) - (length match))) - (with-output-to-temp-buffer "*Completions*" - (display-completion-list allcomp)) - ;; Wait for a keypress. Then delete *Completion* window - (momentary-string-display "" (point)) - (if graphviz-dot-delete-completions - (delete-window - (get-buffer-window (get-buffer "*Completions*")))) - ))))) - -;;;###autoload -(add-to-list 'auto-mode-alist '("\\.dot\\'" . graphviz-dot-mode)) - -;;; graphviz-dot-mode.el ends here -