[comp.lang.icon] GNU Emacs utility for short on-line summary of Icon syntax

sboisen@BBN.COM (Sean Boisen) (05/31/91)

Appended below (in shar format) is a simple GNU Emacs utility that
lets you check the syntax of Icon expressions: for example, while
editing a program, i may forget the arguments to "any". I can then
call the Emacs function describe-icon-symbol, which displays

	any(cset,string,i,j)

Much easier than reaching for the manual!

Richard Goerwitz encouraged me to post it here: no guarantees, but
enjoy. I'd be particularly interested if somebody has more complete
descriptions (mine are only a single line, not always enough to keep
me from reaching for the manual).

........................................
Sean Boisen -- sboisen@bbn.com
BBN Systems and Technologies, Cambridge MA


------------------------------ snip snip ------------------------------
#! /bin/sh
# To extract, remove mail header lines and type "sh filename"
echo x - icon-describe.text
sed -e 's/^X//' > icon-describe.text << '!FaR!OuT!'
XThis is a quick syntax helper for Icon users that work with GNU Emacs.
XThe idea is a simple one: while creating a program, say, you're unsure
Xabout the arguments or their orders for push(). With icon-describe, you
Xsimple execute the function "describe-icon-symbol" with point
Xsomewhere around the word push, and the following information
Xis displayed in the mini-buffer:
X
Xpush(list,x)
X
XThis works with procedures, infix/prefix operators, control
Xstructures/reserved words, and keywords. Note that you get notified if
Xsomething isn't in the documentation file, so you can also use it to
Xcheck whether you've got the right symbol name or not (but you'd have
Xto actually go look at the file to see what the _right_ one is).
X
X
XCaveats:
X
XSee your Emacs manual for how to load this automatically when you
Xvisit .icn files (look at auto-mode-alist and icon-mode-hook, assuming
Xyou're using an icon-mode).
X
Xdescribe-icon-symbol is not initially bound to a key, but you'll
Xprobably want to do so.
X
XThe format of the documentation file is one to a line: this is nice
Xbecause it can be displayed in the minibuffer instead of a pop-up
Xwhich then has to be gotten rid of. It's not so nice in that it limits
Xthe amount of information pretty severely. If somebody wants to
Xprovide a larger documentation file i might provide a pop-up version
X(or some hybrid): i'm too lazy to do all the typing, for one thing!
XThere's also an uneven mix of bare syntax description with some
Xdiscussion of what (especially prefix) operators do. A few keywords
Xhave no description because they're newer than the Icon book, and i
Xdidn't have a description handy. Please contribute to this doc file if
Xyou can!
X
XThe function which determines the symbol at point isn't perfect
X(surprise surprise!). In particular it depends on the syntax tables to
Xdetermine what punctuation is, so if your syntax tables aren't right,
Xthis won't be either. I'm open to suggestions for better algorithms.
XThe current version has a preference for looking backward if not
Xactually on part of a symbol: this seemed more useful for those cases
Xwhere you become hesitant about the arguments to a function just after
Xtyping it.
X
XWhile the usual lack of warranty and support applies, i'd still like
Xto hear if there are problems with this.
X
XSean Boisen
XBBN Systems and Technologies Corporation
X
X
XTwo files follow: i call the first icon-describe.el (don't forget to
Xbyte-compile it!), and the second icondoc.txt. Whatever you decide to
Xcall the latter, make sure you set the variable icon-doc-file accordingly! 
!FaR!OuT!
echo x - icon-describe.el
sed -e 's/^X//' > icon-describe.el << '!FaR!OuT!'
X;;; Icon syntax describer: by Sean Boisen, BBN Systems and
X;;; Technologies Corporation, sboisen@bbn.com. Standard lack of
X;;; warranty applies: may be freely distributed subject to the
X;;; restrictions of the GNU Emacs copyright. Please send me any bug
X;;; fixes and/or improvements!
X;;;
X;;; This still has at least the following known deficiences:
X;;;
X;;; The descriptive text file lacks descriptions for the newer
X;;; keywords. Please add them and send me a version if you can!
X;;;
X;;; It might be nice if icon-symbol-at-point did escape sequences as
X;;; well: it doesn't.
X;;;
X;;; Someday it might be more useful to provide more than one line of
X;;; information, especially for procedures: the main hurdle here is
X;;; that i'm too lazy to type all the text in.
X
X;;; additions:
X;;;
X;;; sboisen 2/23/89: i noticed that &pos gets
X;;; picked up as pos. Hacked describe-icon-symbol for this as a
X;;; special case. Still imperfect if point in just past the colon in
X;;; 0:&pos however...
X;;;
X;;; sboisen 2/23/89: symbols which contain characters with special
X;;; meanings in regexps don't get handled properly! not yet fixed...
X
X(require 'icon-mode)
X
X(provide 'icon-describe)
X
X(defvar icon-doc-file "/d4m/sboisen/emacs/icondoc.txt"
X  "Where the documentation file can be found.")
X
X;; a helper function: get a string containing all the characters matching
X;; some spec in a syntax table. Class is an atom. Useful in conjunction with
X;; skip-chars-forward. Doesn't do the eighth bit.
X
X(defun get-chars-in-class (class syntax-table)
X  (let ((classcode
X	  (cond
X	    ((eq class 'whitespace) 0)
X	    ((eq class 'punctuation) 1)
X	    ((eq class 'word) 2)
X	    ((eq class 'symbol) 3)
X	    ((eq class 'open) 4)	;this doesn't work!
X	    ((eq class 'close) 5)
X	    ((eq class 'prefix) 6)
X	    ((eq class 'stringquote) 7)
X	    ((eq class 'charquote) 9)
X	    ((eq class 'startcomment) 11)
X	    ((eq class 'endcomment) 12)
X	    ))
X	(index 0)
X	(str ""))
X    (while (< index 128)
X      (if (eql (aref syntax-table index) classcode)
X	  (setq str (concat str (char-to-string index))))
X      (setq index (1+ index)))
X    str))
X
X(defvar wordchars "a-zA-Z0-9_")
X(defvar junkchars (concat " \n\t\r" "({[)}]"))
X(defvar punct (get-chars-in-class 'punctuation icon-mode-syntax-table))
X
X(defun icon-symbol-at-point ()
X  "Get the closest Icon symbol to point, but don't change your
X       position. Has a preference for looking backward when not
X       directly on a symbol."
X  (let (start end symbol)
X    (save-excursion
X      ;; first see if you're just past a symbol
X      (if (looking-at "\\s-\\|\\s(\\|\\s)\\|\\s>")
X	  (skip-chars-backward junkchars)
X	;; else move forward one character, presumably either a \w or
X	;; a symbol: but not if at the end of the buffer
X	(or (= (point) (point-max))
X	    (forward-char 1)))
X      
X      (cond
X	;; special case for (potential) keywords: just past a &
X	((eql (preceding-char) 38)
X	 (setq start (1- (point)))
X	 (cond
X	   ((looking-at "\\w")
X	    (skip-chars-forward wordchars))
X	   ((looking-at "\\s.")
X	    (skip-chars-forward punct))
X	   ;; else whitespace?
X	   ))
X	;; just past a \\w
X	((eql (aref icon-mode-syntax-table (preceding-char)) 2)
X	 (skip-chars-backward wordchars)
X	 ;; worry about being in the middle of a keyword
X	 (if (eql (preceding-char) 38)
X	     (setq start (1- (point)))
X	   (setq start (point)))
X	 (skip-chars-forward wordchars))
X	;; else a symbol?
X	(t
X	  (skip-chars-backward punct)
X	  (setq start (point))
X	  (skip-chars-forward punct)))
X      ;; THE OLD WAY THAT LOOKED FORWARD INSTEAD OF BACKWARD
X;;      ;; skip past whitespace and parens
X;;      (while (looking-at "\\s-\\|\\s(\\|\\s)\\|\\s>")
X;;	(skip-chars-forward junkchars))
X;;      (if (looking-at "\\w")
X;;	  (progn
X;;	    (skip-chars-forward wordchars)
X;;	    (setq start (point))
X;;	    (skip-chars-backward wordchars))
X;;	;; else a symbol?
X;;	(progn
X;;	    (skip-chars-forward punct)
X;;	    (setq start (point))
X;;	    (skip-chars-backward punct)))
X      (buffer-substring start (point)))))
X
X(defun describe-icon-symbol (symbol)
X  "Display the documentation of SYMBOL, an Icon operator."
X  (interactive
X    (let ((fn (icon-symbol-at-point))
X	  (enable-recursive-minibuffers t)
X	  (case-fold-search nil)	;require that case match for search
X	  val args-file regexp)
X      (setq val (read-from-minibuffer
X		  (if fn
X		      (format "Symbol (default %s): " fn)
X		    "Symbol: ")))
X      (if (string= val "")
X	  (setq val fn))
X      ;; this may not work for characters which are special to regexp
X      ;; (like ".")
X      (setq regexp (concat "^" val "[ \t(]"))
X      (if (not (get-file-buffer icon-doc-file))
X	  (progn
X	    (setq args-file
X	      (find-file-noselect icon-doc-file))
X	    (set-buffer args-file)
X	    (rename-buffer "*ICON-DOC*")))
X      (set-buffer (get-file-buffer icon-doc-file))
X      (goto-char (point-min))
X      (list (if (re-search-forward regexp (point-max) t)
X	  (save-excursion
X	    (beginning-of-line 1)
X	    (let ((lnstart (point)))
X	      (end-of-line)
X	      (message (buffer-substring lnstart (point)))))
X	(error (format "No definition for %s" val)))))))
!FaR!OuT!
echo x - icondoc.txt
sed -e 's/^X//' > icondoc.txt << '!FaR!OuT!'
XFORMAT: a regexp like "^word(args)" of "^word[\t ]descriptive_text 
Xabs(numeric)
Xany(cset,string,i,j)
Xbal(cset1,cset2,cset3,string,i,j)
Xcenter(string1,i,string2)
Xchar(i)
Xclose(file)
Xcollect()
Xcopy(x)
Xcset(x)
Xdelete(x1,x2)
Xdetab(string,i1,i2,...,in)
Xdisplay(i,file)
Xentab(string,i1,i2,...,in)
Xerrorclear()
Xexit(i)
Xfind(string1,string2,i,j)
Xget(list)
Xgetenv(string)
Xiand(i,j)
Xicom(i)
Ximage(x)
Xinsert(x1,x2,x3)
Xinteger(x)
Xior(i,j)
Xixor(i,h)
Xishift(i,j)
Xleft(string1,i,string2)
Xlist(i,x)
Xmany(cset,string,i,j)
Xmap(string1,string2,string3)
Xmatch(string1,string2,i,j)
Xmember(x1,x2)
Xmove(i)
Xnumeric(x)
Xopen(string1,string2)
Xord(string)
Xpop(list)
Xpos(i)
Xproc(x)
Xpull(list)
Xpush(list,x)
Xput(list,x)
Xread(file)
Xreads(file,i)
Xreal(x)
Xremove(string)
Xrename(string1,string2)
Xrepl(string,i)
Xreverse(string)
Xright(string1,i,string2)
Xrunerr(i,x)
Xsave(string)
Xseek(file,i)
Xseq(i,j)
Xset(list)
Xsort(list)
Xsort(table,i)
Xstop(x1,x2,...,xn)
Xstring(x)
Xsystem(string)
Xtab(i)
Xtable(x)
Xtrim(string,cset)
Xtype(x)
Xupto(cset,string,i,j)
Xwhere(file)
Xwrite(x1,x2,...,xn)
Xwrites(x1,x2,...,xn)
XCONTROL STRUCTURES/RESERVED WORDS
Xbreak expr
Xby	i to j by k
Xcase expr of {...}
Xcreate x
Xdefault : expr
Xdo	every expr1 do expr2; until expr1 do expr2; while expr1 do expr2
Xdynamic identifiers
Xelse	if expr1 then expr2 else expr3
Xend 
Xevery expr1 do expr2
Xfail 
Xglobal identifiers
Xif expr1 then expr2 else expr3
Xinitial expr
Xlink file1,file2,...filen
Xlocal identifiers
Xnext 
Xnot expr
Xof	case expr of {...}
Xprocedure identifier(identifiers)
Xrecord identifiers(fields)
Xrepeat expr
Xreturn expr
Xstatic identifiers
Xsuspend expr
Xthen	if expr1 then expr2 else expr3
Xto	i to j by k
Xuntil expr1 do expr2
Xwhile expr1 do expr2
X|	expr1 | expr2; |expr
X\	expr \ i ; \x produces x if x is not null, otherwise fails
X?:=	s ?:= x
X?	s ? x; ?x produces a random element of x, failing if x is empty
XINFIX OPERATIONS
X+	n + m produces the sum of n and m; +n produces the numeric value of n
X-	n - m produces the difference of n and m; -n produces the negative of n
X*	n * m produces the product of n and m; *x produces the size of x
X/      n / m produces n divided by m; /x produces x if x is null, or else fails
X%	n % m	produces the remainder of n divided by m
X^	n ^ m produces n to the power of m; ^e produces a refreshed copy of e
X<	n < m produces m if n is less than m, else fails
X<=	n <= m produces m if n is less than or equal to m, else fails
X=	n = m produces m if n equals m, else fails; =s equiv. to tab(match(s))
X>=	n >= m produces m if n is greater than or equal to m, else fails
X>	n > m produces m if n is greater than m, else fails
X~=	n ~= m produces m if n is not equal to m, else fails
X++	c1 ++ c2 produces the cset union of c1 and c2
X--	c1 -- c2 produces the cset difference of c1 and c2
X**	c1 ** c2 produces the cset intersection of c1 and c2
X||	s1 || s2 produces a string consisting of s1 followed by s2
X<<	s1 << s2  produces s2 if s1 is lexically less than s2, else fails
X<<=	s1 <<= s2  produces s2 if s1 is lexically <= s2, else fails
X==	s1 == s2 produces s2 if s1 is lexically equal to s2, else fails
X>>=	s1 >>= s2 produces s2 if s1 is lexically >= s2, else fails
X>>	s1 >> s2 produces s2 if s1 is lexically greater than s2, else fails
X~==	s1 ~== s2 produces s2 if s2 isn't lexically equal to s2, else fails
X|||	a1 ||| a2 produces a list of the values of a1 followed by those of a2
X@	x @ e activates e and transmits x to it; @e produces the outcome of activating e
X:=	x := y assigns the value of y to x, and produces the variable x
X<-	x <- y assigns y to x and produces x; reverses assignment if resumed
X:=:	x :=: y exchanges the values of x and y and produces the variable x
X<->	x <-> y exchanges x and y and produces x; reverses exchange if resumed
X===	x === y produces y if x and y have the same value, else fails
X~===	x ~=== y produces y if x and y don't have the same value, else fails
X&	x & y produces y; produces a variable if y is a variable
X.	x . y produces a variable for the y field of record x
X+:=	n +:= m assigns the sum of n and m to n and produces n
X-:=	n -:= m assigns the difference of n and m to n and produces n
X*:=	n *:= m assigns the product of n and m to n and produces n
X/:=	n /:= m assigns the difference of n and m to n and produces n
X%:=	n %:= m assigns the remainder of n divided by m to n and produces n
X^:=	n ^:= m assigns n raised to the power m to n and produces n
X<:=	n <:= m assigns m to n if n < m, else fails; produces n
X<=:=	n <=:= m assigns m to n if n <= m, else fails; produces n
X=:=	n =:= m assigns m to n if n = m, else fails; produces n
X>=:=	n >=:= m assigns m to n if n >= m, else fails; produces n
X>:=	n >:= m assigns m to n if n > m, else fails; produces n
X~=:=	n ~=:= m assigns m to n if n ~= m, else fails; produces n
X++:=	c1 ++:= c2 assigns the cset union of c1 and c2 to c1 and produces c1
X--:=	c1 --:= c2 assigns the cset difference of c1 and c2 to c1, producing c1
X**:=	c1 **:= c2 assigns the intersection of c1 and c2 to c1, producing c1
X||:=	s1 ||:= s2 assigns the string s1 || s2 to s1 and produces s1
X<<:=	s1 <:= s2 assigns s2 to s1 if s1 << s2, else fails; produces s1
X<<=:=	s1 <=:= s2 assigns s2 to s1 if s1 <<= s2, else fails; produces s1
X==:=	s1 =:= s2 assigns s2 to s1 if s1 == s2, else fails; produces s1
X>>=:=	s1 >=:= s2 assigns s2 to s1 if s1 >>= s2, else fails; produces s1
X>>:=	s1 >:= s2 assigns s2 to s1 if s1 >> s2, else fails; produces s1
X~==:=	s1 ~=:= s2 assigns s2 to s1 if s1 ~== s2, else fails; produces s1
X|||:=	a1 |||:= a2 assigns to a1 the concatenation of a1 and a2; produces a1
X@:=	x @:= e activates e with the value of x, and assigns the result to x
X===:=	x ===:= y assigns y to x if x === y, else fails; produces x
X~===:=	x ~===:= y assigns y to x if x ~=== y, else fails; produces x
X&:=	x &:= y assigns the value of y to x and produces x
XPREFIX OPERATIONS (some under infix instead)
X~	~c produces the cset complement of c with respect to &cset
X!	!x generates the elements of x, failing if x is empty (x may be a file)
X.	.x produces the value of x
XKEYWORDS
X&ascii	produces a cset of the 128 ASCII characters
X&clock	produces a string consisting of the current time of day
X&collections	
X&cset	produces a cset consisting of all 256 characters
X&current	
X&date	produces a string consisting of the current date
X&dateline	produces a string of the current date and time of day
X&digits
X&error
X&errornumber
X&errortext
X&errorvalue
X&errout	produces the standard error output file
X&fail	fails
X&features
X&file
X&host	produces a string that identifies the host computer
X&input	produces the standard input file
X&lcase	produces a cset consisting of the 26 lowercase letters
X&level	produces the integer level of the current procedure call
X&line
X&main	produces a co-expression for the initial call of main
X&null	produces the null value
X&output	produces the standard output file
X&pos	produces the integer position of scanning in &subject
X&random	produces the value of the seed for the psuedo-random sequence
X&regions
X&source	produces a co-expression for the activator of the current co-expression
X&storage	how much of each storage region is currently being used
X&subject	produces the variable whose value is the string being scanned
X&time	produces the integer number of msecs since beginning of execution
X&trace	produces a variable whose value controls procedure tracing
X&ucase	produces a cset consisting of the 26 uppercase characters
X&version	produces a string that identifies the version of Icon
!FaR!OuT!
exit