podar@sbcs.UUCP (Sunil Podar) (06/24/85)
here it is folks: the word completion package. There is detailed documentation in the files below. I have included two dictionaries too, which for convenience sake I have named the dictionary files differently; you will have to mv the dict.latex & dict.pascal files to ~/.dict.latex & ~/.dict.pascal ; the pascal dictionary file is just an experimental one and is not complete whereas the latex one is fairly complete. You will have to create other mode dictionaries yourself. Remember to remove any signature at the end of this file before running thru' sh. enjoy. any comments welcome. ------cut-here-including-this-line----cut-here-including-this-line-------- #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # dictionary.ml # dict.latex # dict.pascal # This archive created: Sun Jun 23 17:55:43 1985 export PATH; PATH=/bin:$PATH echo shar: extracting "'dictionary.ml'" '(15491 characters)' if test -f 'dictionary.ml' then echo shar: over-writing existing file "'dictionary.ml'" fi cat << \SHAR_EOF > 'dictionary.ml' ; podar@sbcs (Sunil Podar) June 23, 1985 (SUNY at Stony Brook) ; any followups to: ; CSNET: podar@sbcs.csnet ; ARPA: podar%suny-sb.csnet@csnet-relay.arpa ; UUCP: {allegra, hocsd, philabs, ogcvax}!sbcs!podar ; mail: Sunil Podar, Dept of Comp. Science ; SUNY at Stony Brook, N.Y. 11794 ; ; BUFFER/MODE-SPECIFIC DICTIONARIES AND WORD COMPLETION. ; ------------------------------------------------ ; 1. fisrt set of functions: intext word completion ; 2. second set of functions at the end: "get-tty-..." emulation. ; ; These functions provide intext word expansion similar to the ; command completion feature of emacs on buffer names & ; command-names. It is also similar to the abbrev mode but easier to ; use and slower. It uses a dictionary of words and helps by filling ; unique suffices of words being expanded. ; ; The idea is to type a first few characters and type expansion-key ; (currently bound to ESC-space) and the suffix of the word to the ; left of dot is filled in, if any, and if there are choices then ; they are shown in a Help window. ; ; The setup here is fairly general, although it has been written ; primarily to help with typing long words in LaTeX. This package ; provides the facility of having separate dictionaries for different ; kinds of files i.e. it can be mode-dependent. The words on which ; such expansion will work are to be maintained in dictionary files ; whose names must follow these conventions. ; ; ~/.dict.<mode>[.local] ; ~/.dict.global ; ; <mode> can be any word you chose, e.g. latex, pascal, junk, c, etc. ; ; E.g. for latex, we MUST have a ~/.dict.latex and we MAY have a ; ~/.dict.latex.local file, which if exists will also become part of ; the dictionary. The ~/.dict.global file is also loaded if it ; exists. The idea of such a setup is that .<mode> files will have ; the standard words, .<mode>.local can have any other words that are ; used in that particular mode and one wants them expanded too such ; as long variable names, and this file can be purged from time to ; time as the usage changes. The .dict.global is meant for words that ; are globally used such as your name, university etc. .dict.global ; file is always loaded into each dictionary irrespective of the ; mode. ; ; The conventions used for dictionary can be easily changed to suit ; ones' need if there is any conflict or dislike for above. The ; function "setup-dictionary-expansion" below will have to be modified ; accordingly. All that is finally required by the setup here is that ; there be ONE dictionary buffer associated with each buffer, and does ; not depend on how the dictionary files are maintained and how the ; dictionary buffer is constructed. ; ; A simple function "add-word-to-local-dictionary" is also provided ; that goes into recursive-edit and takes a region between mark & dot ; as the word to be added to the local dictionary. It also loads the ; word into current dictionary buffer making it imediately available ; for expansion. The word thus added are added only to the ".....local" ; dictionary and it is your responsibility to make sure it is unique. ; You have to explicitly add words to the other ".<mode>" and ; ".dict.global" dictionaries. The function can be executed interactively ; by typing "ESCx add-word-to-local-dictionary". ; ; There are two ways to go about setting up this package. ; 1. EXPLICIT WAY: ; From any buffer, type "ESCx load dictionary.ml", followed by ; "ESCx setup-dictionary-expansion" which will ask you for name of ; dictionary to which you must reply with the appropriate name of the ; form "~/.dict.<mode>". The .....local & the .global dictionaries ; are automatically loaded if they exist. ; ; 2. AUTOMATED WAY: there are again two ways(!): ; a. add this one line to EVERY <mode.ml> file that puts emacs in a ; specific mode depending on the file pattern: ; ; (setup-dictionary-expansion "~/.dict.<mode>") ; where <mode>= pascal, latex, prolog, c, etc. ; and add the following line in your .emacs_[pro|local] : ; (autoload "setup-dictionary-expansion" "...../dictionary.ml") ; ; b. If you do not wish to fiddle with the library mode files, then ; you have to write a small defun for EACH mode and add them to ; your .emacs_[pro|local] file, e.g.: ; ; (autoload "setup-dictionary-expansion" "...../dictionary.ml") ; (auto-execute "latex-dictionary-expansion" "*.tex") ; (defun (latex-dictionary-expansion ; (setup-dictionary-expansion "~/.dict.latex"))) ; ; (auto-execute "pascal-dictionary-expansion" "*.p") ; (defun (pascal-dictionary-expansion ; (setup-dictionary-expansion "~/.dict.pascal"))) ; ; 3. and of course have your dictionaries setup beforehand. ; ; NOTE: If you ever manipulate the dictionaries explicitely by ; editing the files remember to make sure there are NO DUPLICATES. It ; is not necessary to have the files sorted, though one simple way ; from within emacs is to enclose the whole buffer in a region (put ; mark at end-of-file and go to beginning-of-file) and then type ; "ESCxfilter-region sort -u" and then a write-file. ; ; Thats all folks, enjoy. Do let me know of any bugs or if you make ; any modifications or would like to change something and can't ; figure out how to. You are permitted to continue using the abbrev ; expansion feature of emacs although it is worth considering giving ; it up. ; PS: This program ought to be written in C using grep/look etc. ; with an interface to emacs or using the emacs C code to maintain ; tables just like for "get-tty-buffer"; and perhaps a different ; dictionary organization along the lines of spell. I do not know C ; yet hence you are welcome to do so and please let me know if you do. ;------------------------------------------------------------------------ (declare-buffer-specific &dictionaryfile &dictionarybuffer) (defun (setup-dictionary-expansion dictfile (setq &dictionaryfile (arg 1 "name of file containing dictionary? ")) (setq &dictionarybuffer (substr &dictionaryfile -10 10)) (setq dictfile &dictionaryfile) (save-excursion (temp-use-buffer &dictionarybuffer) (if (= (buffer-size) 0) (progn (setq needs-checkpointing 0) (insert-file dictfile) (if (file-exists "~/.dict.global") (insert-file "~/.dict.global")) (if (file-exists (concat dictfile ".local")) (insert-file (concat dictfile ".local"))) ) ) ) (local-bind-to-key "intext-word-completion" "\^[ ") ; ESC-space ; could use ^[^[ or ^\ )) ; for add-word-to-dictionary see documentation above. (defun (add-word-to-local-dictionary (save-excursion word yesno dictfile dictbuffer (setq dictfile &dictionaryfile) (setq dictbuffer &dictionarybuffer) (message "define a region between mark & dot defining" " the dict. word, then type ^C") (setq mode-line-format (concat "adding word to " dictfile ".local " "(^C to define word & resume editing)")) (recursive-edit) (setq word (region-to-string)) (if (> (length word) 0) (progn (message "add " """" word """" " to dictionary? (y/n) ") (setq yesno (char-to-string (get-tty-character)))) (setq yesno "n") ) (setq mode-line-format default-mode-line-format) (if (= yesno "y") (progn (temp-use-buffer "*match-buf*") (erase-buffer) (insert-string (concat word "\n")) (set-mark)(beginning-of-file) (append-region-to-buffer dictbuffer) (append-to-file (concat dictfile ".local")) (message """" word """" " added to buffer & " (concat dictfile ".local")) ) (message "Aborted.") ) ) )) ; intext-word-completion picks up the word to the left of dot in the current ; buffer and calls the function "occurances-of-prefix" passing the picked-up- ; word as given prefix and fills in unique suffix in the text if one found. ; it complains (^G) if no word with the given word found, shows choices in ; a Help buffer if more than one choice. If a suffix (unique or not) of ; >= one character is found then it is filled in. ; NOTE: since just one word to the left of dot is picked up the expansion ; will work only with that word as the prefix hence no spaces allowed in ; the prefix that you have when you type ESC-space. The dictionary can of ; course have any thing; for example if a dictionary word looked like: ; program main (input, output); ; then in the text buffer any prefix of the word "program" will be expanded ; but not if the scenario was "program m<ESC >" since only the "m" will be ; picked up. (defun (intext-word-completion fullword (set-mark) (backward-word) (exchange-dot-and-mark) (setq fullword (occurances-of-prefix (region-to-string))) (if (= fullword "\^G") (error-message "no word in dictionary with the given prefix.") (= fullword (region-to-string)) (display-choice) (progn (if (= (substr fullword 1 1) "\^G") (setq fullword (substr fullword 2 -1))) (delete-to-killbuffer) (insert-string fullword) ) ) )) ; occurances-of-prefix essentially greps all the words with the given prefix ; and puts them into *match-buf* and returns info about the results: ; it returns "^G" if no word with the given prefix found, ; (concat "^G" word) if a unique word with given prefix is found, ; the ^G is not really needed here but I needed ; it for "get-tty-dictionary-word" below. ; It is stripped away by the function ; "intext-word-completion" above. ; largest-common-prefix from the words that matched the given ; prefix. If no additional characters are found ; then the choices are shown in a ; poped-up-buffer. ; PS: could use fast-filter-region and grep ^givenprefix on dictionarybuffer ; of course after copying it into *match-buf* or directly on the files. (defun (occurances-of-prefix givenprefix1 i firstword (setq givenprefix1 (arg 1)) (save-excursion (setq i 0) (temp-use-buffer "*match-buf*") (setq needs-checkpointing 0) (erase-buffer) ) (save-excursion (temp-use-buffer &dictionarybuffer) (beginning-of-file) (while (! (error-occurred (re-search-forward (concat "^" givenprefix1)))) (setq i (+ i 1)) (if (= i 1) (progn (beginning-of-line) (set-mark) (end-of-line) (setq firstword (region-to-string))) ) (beginning-of-line) (set-mark)(end-of-line)(forward-character) (append-region-to-buffer "*match-buf*") ) (if (= i 0) "\^G" (= i 1) (concat "\^G" firstword) ; ^G => unique, klugy way (largest-common-prefix givenprefix1) ) ) )) ; largest-common-prefix works on *match-buf* buffer where it expects strings ; one per line which have a given common prefix. These are picked out from ; the dictionary buffer. It returns the largest common prefix among all those ; strings (a "" if that's the case). (defun (largest-common-prefix n lcprefix (save-excursion (temp-use-buffer "*match-buf*") (beginning-of-file) (set-mark)(end-of-line) (setq lcprefix (region-to-string)) (next-line) (while (& (!= lcprefix (arg 1)) (! (eobp))) (setq n (+ (length (arg 1)) 1)) (beginning-of-line) (set-mark)(end-of-line) (while (= (substr lcprefix 1 n) (substr (region-to-string) 1 n)) (setq n (+ n 1)) ) (setq lcprefix (substr lcprefix 1 (- n 1))) (next-line) ) ) lcprefix )) (defun (display-choice (save-excursion (pop-to-buffer "Help") (setq needs-checkpointing 0) (erase-buffer) (insert-string "Choose one of the following:\n") (yank-buffer "*match-buf*") (beginning-of-file) ) )) ;---------------------------------------------------------------------- ; "get-tty-...." emulation for words from dictionary. This is a separate ; set of functions and not needed for intext-word-completion. The emulation ; also differs in its aim: here the aim is to insert the completed word in ; the buffer. ;----------------------------------------------------------------------- (local-bind-to-key "get-tty-dictionary-word" "\^\") (defun (get-tty-dictionary-word (help-word-completion "dictionary-word: ") )) ; if "get-tty-dictionary-word" is to be bound to a regular key, such as \ ; for LaTeX, then we will have to arrest all the chars such as ;,><=.... ; that immediately follow the \ since they are not in the dictionary; ; which means have a separate function such as the following (perhaps not ; exactly) which will also be responsible for inserting the \ in text; the ; dictionary does not have \ at the beginning of words. ; (defun (dictionary-word-arrest-non-alpbabets char prompt ; (message (arg 1)) ; (setq char (get-tty-character)) ; (if (| (& (>= char 48)(<= char 57)) ; 0..9 these ranges are ; (& (>= char 64)(<= char 90)) ; @A..Z not perfect. ; (& (>= char 97)(<= char 122)) ; a..z ; ) ; (progn (push-back-character char) ; (help-word-completion (arg 1))) ; (= char 7) ; ^G ; (error-message "Aborted.") ; (insert-character char) ; ) ; )) ; ; The following function emulates "get-tty-..." command with all the bells & ; whistles and helps you with completion of words from a dictionary.The only ; difference here is that since "get-tty-character" is used to get chars, the ; cursor remains in the buffer area while the word completion is going on. ; couldn't get recursion working because of local variables, hence had to ; use the dirty way using "done". ; (defun (help-word-completion char givenprefix filledword done prompt (setq prompt (arg 1)) (setq givenprefix "") (setq done 0) (while (!= done 1) (setq char 0) (message (concat prompt givenprefix)) (while (& (!= char 32)(!= char 63)(!= char 7)(!= char 13)) (setq char (get-tty-character)) (if (| (= char 8) (= char 127)) (setq givenprefix (substr givenprefix 1 -1)) (setq givenprefix (concat givenprefix (char-to-string char))) ) (message (concat prompt givenprefix)) ) (setq givenprefix (substr givenprefix 1 -1)) ; to get rid of ; 32/63/7/13 char (if (= char 7) (error-message "Aborted.") (progn (setq filledword (occurances-of-prefix givenprefix)) (if (= char 63) (display-choice) (= filledword "\^G") ; no word with given prefix (send-string-to-terminal "\^G") (= (substr filledword 1 1) "\^G") ; uniq string found (progn (insert-string (substr filledword 2 -1)) (message "") (setq done 1) ) (> (length filledword) (length givenprefix)) (setq givenprefix filledword) (= char 13) ; ^M & prefix is a valid word (progn (insert-string givenprefix) (message "") (setq done 1) ) (display-choice) ; pop show choices ) ) ) ) ; while not done )) SHAR_EOF if test 15491 -ne "`wc -c 'dictionary.ml'`" then echo shar: error transmitting "'dictionary.ml'" '(should have been 15491 characters)' fi echo shar: extracting "'dict.latex'" '(3646 characters)' if test -f 'dict.latex' then echo shar: over-writing existing file "'dict.latex'" fi cat << \SHAR_EOF > 'dict.latex' Alph Downarrow Huge LARGE Large Leftarrow Leftrightarrow Longleftarrow Longleftrightarrow Longrightarrow Rightarrow Roman Uparrow Updownarrow acute addtocontents addtocontentsline addtocounter addtolength aleph amalg approx arabic arccos arcsin arctan arg arraycolsep arrayrulewidth arraystretch ast asymp backslash baselineskip baselinestretch begin beginlistoffigures beginlistoftables begintableofcontents bibitem bigcap bigcirc bigcup bigdot bigoplus bigotimes bigskip bigskipamount bigsqcup bigtriangledown bigtriangleup biguplus bigvee bigwedge blackandwhite boldmath bot bottomfraction bowtie breve cal cap caption cdot cdots chapter check circ circle circle* cleardoublepage clearpage clubsuit colorslides columnsep columnseprule columnwidth cong contentsline coprod copyrightspace cos cosh coth csc cup dashbox dashv dblfloatpagefraction dblfloatsep dbltextfloatsep ddagger ddot deg det diamondsuit dim displaymath displaystyle div documentstyle doteq dotfill doublerulesep downarrow ell em emptyset end epsilon eqnarray equiv evensidemargin exp fbox fboxrule fboxsep fleqn floatpagefraction floatsep flushbottom flushleft flushright fnsymbol fontsize footheight footnotemark footnotesep footnotesize footnotetext footskip forall frac framebox gcd geq glossaryentry grave hat hbar headheight headsep heartsuit hfill hline hoare hom hookleftarrow hookrightarrow hrulefill hspace huge imath include includeonly indexentry indexspace inf infty int intextsep it itemindent itemsep jmath ker kill label labelwidth large lceil ldots leadsto leftarrow leftharpoondown leftharpoonup leftmargin leftmargini leftmarginii leftmarginiii leftmarginiv leftmarginv leftmarginvi leftrightarrow leftrightharpoons leq leqno lfloor lhd lim liminf limsup line linebreak linethickness linewidth listoffigures listoftables listparindent log longleftarrow longleftrightarrow longmapsto longrightarrow makebox makeglossary makeindex makelabels maketitle mapsto marginpar marginparpush marginparsep marginparwidth mathindent max mbox medskip medskipamount mho mid min minipage mit multicolumn multiput nabla nearrow neg newcommand newcounter newenvironment newlength newline newpage newsavebox newtheorem nofiles noindent nolinebreak nopagebreak normalmarginpar normalsize nwarrow obeycr oddsidemargin odot oint ominus onecolumn onlynotes onlyslides oplus oslash otimes oval overbrace overline pagebreak pagenumbering pageref pagestyle parallel parbox parindent parsep parskip parstretch partial partopsep perp phi poptabs prec preceq prod propto pushtabs put raggedbottom raggedright raisebox rangle rceil ref renewcommand renewenvironment restorecr reversemarginpar rfloor rhd rho rightarrow rightharpoondown rightharpoonup rightmargin rm savebox sbox sc scriptscriptsize scriptscriptstyle scriptsize scriptstyle searrow sec section setcounter setlength setminus settowidth sf shortstack sigma sim simeq sin sinh sl small smallskip smallskipamount spadesuit sqcap sqcup sqrt sqsubset sqsubseteq sqsupset sqsupseteq stackrel subitem subsection subseteq subsubitem subsubsection succ succeq sup supset supseteq surd swarrow tabbingsep tabcolsep tableofcontents tan tanh textfloatsep textfraction textheight textstyle textwidth thebibliography thechapter theindex thesection theta thicklines thinlines thispagestyle tilde tiny titlepage tocdepth topfraction topmargin topnumber topsep totalnumber triangleleft triangleright tt twocolumn twoside typein typeout unboldmath underbrace underline unitlength unlhd unrhd uparrow updownarrow uplus usebox usecounter varepsilon varphi varrho varsigma vartheta vdash vec vector vee verbatim vline vspace widehat widetilde SHAR_EOF if test 3646 -ne "`wc -c 'dict.latex'`" then echo shar: error transmitting "'dict.latex'" '(should have been 3646 characters)' fi echo shar: extracting "'dict.pascal'" '(103 characters)' if test -f 'dict.pascal' then echo shar: over-writing existing file "'dict.pascal'" fi cat << \SHAR_EOF > 'dict.pascal' begin const end function procedure program main (input, output); type var reset rewrite readln writeln SHAR_EOF if test 103 -ne "`wc -c 'dict.pascal'`" then echo shar: error transmitting "'dict.pascal'" '(should have been 103 characters)' fi # End of shell archive exit 0 -- Sunil Podar SUNY at Stony Brook CSNET: podar@sbcs.csnet ARPA: podar%suny-sb.csnet@csnet-relay.arpa UUCP: {allegra, hocsd, philabs, ogcvax} !sbcs!podar