tf5-5.0beta8/.git/
tf5-5.0beta8/.git/info/
tf5-5.0beta8/.git/logs/
tf5-5.0beta8/.git/logs/refs/heads/
tf5-5.0beta8/.git/objects/00/
tf5-5.0beta8/.git/objects/01/
tf5-5.0beta8/.git/objects/04/
tf5-5.0beta8/.git/objects/05/
tf5-5.0beta8/.git/objects/07/
tf5-5.0beta8/.git/objects/09/
tf5-5.0beta8/.git/objects/0a/
tf5-5.0beta8/.git/objects/0c/
tf5-5.0beta8/.git/objects/0e/
tf5-5.0beta8/.git/objects/12/
tf5-5.0beta8/.git/objects/13/
tf5-5.0beta8/.git/objects/14/
tf5-5.0beta8/.git/objects/16/
tf5-5.0beta8/.git/objects/17/
tf5-5.0beta8/.git/objects/19/
tf5-5.0beta8/.git/objects/1c/
tf5-5.0beta8/.git/objects/1d/
tf5-5.0beta8/.git/objects/1e/
tf5-5.0beta8/.git/objects/1f/
tf5-5.0beta8/.git/objects/20/
tf5-5.0beta8/.git/objects/21/
tf5-5.0beta8/.git/objects/23/
tf5-5.0beta8/.git/objects/27/
tf5-5.0beta8/.git/objects/29/
tf5-5.0beta8/.git/objects/2a/
tf5-5.0beta8/.git/objects/2b/
tf5-5.0beta8/.git/objects/2f/
tf5-5.0beta8/.git/objects/30/
tf5-5.0beta8/.git/objects/33/
tf5-5.0beta8/.git/objects/34/
tf5-5.0beta8/.git/objects/35/
tf5-5.0beta8/.git/objects/39/
tf5-5.0beta8/.git/objects/3c/
tf5-5.0beta8/.git/objects/3d/
tf5-5.0beta8/.git/objects/3f/
tf5-5.0beta8/.git/objects/40/
tf5-5.0beta8/.git/objects/41/
tf5-5.0beta8/.git/objects/42/
tf5-5.0beta8/.git/objects/44/
tf5-5.0beta8/.git/objects/46/
tf5-5.0beta8/.git/objects/47/
tf5-5.0beta8/.git/objects/48/
tf5-5.0beta8/.git/objects/4a/
tf5-5.0beta8/.git/objects/4d/
tf5-5.0beta8/.git/objects/4f/
tf5-5.0beta8/.git/objects/53/
tf5-5.0beta8/.git/objects/54/
tf5-5.0beta8/.git/objects/58/
tf5-5.0beta8/.git/objects/5b/
tf5-5.0beta8/.git/objects/5c/
tf5-5.0beta8/.git/objects/5e/
tf5-5.0beta8/.git/objects/5f/
tf5-5.0beta8/.git/objects/60/
tf5-5.0beta8/.git/objects/61/
tf5-5.0beta8/.git/objects/62/
tf5-5.0beta8/.git/objects/63/
tf5-5.0beta8/.git/objects/66/
tf5-5.0beta8/.git/objects/67/
tf5-5.0beta8/.git/objects/6c/
tf5-5.0beta8/.git/objects/6e/
tf5-5.0beta8/.git/objects/72/
tf5-5.0beta8/.git/objects/73/
tf5-5.0beta8/.git/objects/75/
tf5-5.0beta8/.git/objects/77/
tf5-5.0beta8/.git/objects/7a/
tf5-5.0beta8/.git/objects/7b/
tf5-5.0beta8/.git/objects/7c/
tf5-5.0beta8/.git/objects/7e/
tf5-5.0beta8/.git/objects/7f/
tf5-5.0beta8/.git/objects/81/
tf5-5.0beta8/.git/objects/84/
tf5-5.0beta8/.git/objects/86/
tf5-5.0beta8/.git/objects/87/
tf5-5.0beta8/.git/objects/88/
tf5-5.0beta8/.git/objects/8b/
tf5-5.0beta8/.git/objects/8c/
tf5-5.0beta8/.git/objects/8f/
tf5-5.0beta8/.git/objects/91/
tf5-5.0beta8/.git/objects/93/
tf5-5.0beta8/.git/objects/96/
tf5-5.0beta8/.git/objects/97/
tf5-5.0beta8/.git/objects/99/
tf5-5.0beta8/.git/objects/9a/
tf5-5.0beta8/.git/objects/9b/
tf5-5.0beta8/.git/objects/9c/
tf5-5.0beta8/.git/objects/9d/
tf5-5.0beta8/.git/objects/9e/
tf5-5.0beta8/.git/objects/a1/
tf5-5.0beta8/.git/objects/a3/
tf5-5.0beta8/.git/objects/a4/
tf5-5.0beta8/.git/objects/a6/
tf5-5.0beta8/.git/objects/a7/
tf5-5.0beta8/.git/objects/a8/
tf5-5.0beta8/.git/objects/a9/
tf5-5.0beta8/.git/objects/ab/
tf5-5.0beta8/.git/objects/ac/
tf5-5.0beta8/.git/objects/ae/
tf5-5.0beta8/.git/objects/b1/
tf5-5.0beta8/.git/objects/b2/
tf5-5.0beta8/.git/objects/b3/
tf5-5.0beta8/.git/objects/b7/
tf5-5.0beta8/.git/objects/b9/
tf5-5.0beta8/.git/objects/bb/
tf5-5.0beta8/.git/objects/bc/
tf5-5.0beta8/.git/objects/bd/
tf5-5.0beta8/.git/objects/bf/
tf5-5.0beta8/.git/objects/c0/
tf5-5.0beta8/.git/objects/c1/
tf5-5.0beta8/.git/objects/c2/
tf5-5.0beta8/.git/objects/c3/
tf5-5.0beta8/.git/objects/c5/
tf5-5.0beta8/.git/objects/c7/
tf5-5.0beta8/.git/objects/ca/
tf5-5.0beta8/.git/objects/ce/
tf5-5.0beta8/.git/objects/d1/
tf5-5.0beta8/.git/objects/d3/
tf5-5.0beta8/.git/objects/d4/
tf5-5.0beta8/.git/objects/d5/
tf5-5.0beta8/.git/objects/d8/
tf5-5.0beta8/.git/objects/d9/
tf5-5.0beta8/.git/objects/dc/
tf5-5.0beta8/.git/objects/dd/
tf5-5.0beta8/.git/objects/e1/
tf5-5.0beta8/.git/objects/e4/
tf5-5.0beta8/.git/objects/e5/
tf5-5.0beta8/.git/objects/e6/
tf5-5.0beta8/.git/objects/e7/
tf5-5.0beta8/.git/objects/e8/
tf5-5.0beta8/.git/objects/ea/
tf5-5.0beta8/.git/objects/eb/
tf5-5.0beta8/.git/objects/ed/
tf5-5.0beta8/.git/objects/ee/
tf5-5.0beta8/.git/objects/ef/
tf5-5.0beta8/.git/objects/f0/
tf5-5.0beta8/.git/objects/f4/
tf5-5.0beta8/.git/objects/f5/
tf5-5.0beta8/.git/objects/f6/
tf5-5.0beta8/.git/objects/f8/
tf5-5.0beta8/.git/objects/f9/
tf5-5.0beta8/.git/objects/fa/
tf5-5.0beta8/.git/objects/fb/
tf5-5.0beta8/.git/objects/fc/
tf5-5.0beta8/.git/objects/fd/
tf5-5.0beta8/.git/refs/heads/
tf5-5.0beta8/.git/refs/tags/
tf5-5.0beta8/autom4te.cache/
tf5-5.0beta8/macos/
tf5-5.0beta8/unix/
tf5-5.0beta8/win32/
;;;; Completion.
;; This allows you to type part of a word, hit a special key, and have
;; the rest of the word filled in for you automagically.  ESC TAB attempts
;; to complete based on context, or from a user defined list of words;
;; a few other bindings will do more explicit completions.
;;
;; To use:  /load this file, and optionally store a list of words in
;; %{completion_list}.  For example, add this to your ~/.tfrc file:
;;
;;    /load complete.tf
;;    /set completion_list=Hawkeye TinyFugue tinyfugue.sourceforge.net
;;
;; Completion keys:
;;
;; ESC TAB	complete from context, input history, or %{completion_list}.
;; ESC ;	complete from %{completion_list}.
;; ESC i	complete from input history.
;; ESC /	filename completion (UNIX only).
;; ESC @	hostname completion.
;; ESC %	variable name completion.
;; ESC $	macro name completion.
;; ESC ^W	world name completion.

;; By "from context", I mean it will look for patterns and decide which
;; type of completion to use.  For example, if the line begins with "/load",
;; it will use filename completion; if the word begins with "%" or "%{", it
;; will use variable name completion; etc.

;; Optional user extensions.
;; To add your own completion, write a macro with a name like complete_foo
;; which takes the partial word as an argument, and calls /_complete_from_list
;; with the partial word and a list of possible matches.  Then bind a key
;; sequence that calls "/complete foo", and/or add a context
;; sensitive call in "/complete_context".

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

/loaded __TFLIB__/complete.tf

/require lisp.tf

/def -i key_esc_tab = /complete
/def -ib'^[;'	= /complete user_defined
/def -ib'^[i'	= /complete input_history
/def -ib'^[/'	= /complete filename
/def -ib'^[@'	= /complete hostname
/def -ib'^[%'	= /complete variable
/def -ib'^[$'	= /complete macroname
/def -ib'^[^W'	= /complete worldname

; /def -ib'^[~'	= /complete playername  (not implemented)
; /def -ib'^[!'	= /complete command     (not implemented)

;; /complete_playername is difficult to do correctly because of mud delays,
;; and is not portable to different muds, so it is not implemented here.


/def -i complete = \
    /complete_%{1-context} $(/last $[kbhead()])


;; /_complete_from_list <word> <list...>
;; <word> is the partial word to be completed.
;; <list> is a list of possible matches.
;; If <word> matches exactly one member of <list>, that member will be
;; inserted in the input buffer.  If multiple matches are found, the
;; longest common prefix will be inserted; if this is not the first time
;; this identical list of matches has been generated, the list will
;; be displayed.  If no matches are found, it simply beeps.
;; If exactly one match was found, %{_completion_suffix} or a space
;; will be appended to the completed word.
;; If the local variable %{_need_unique} is true, the list will be run
;; through /unique.

/def -i _complete_from_list = \
    /let _prefix=%1%;\
    /shift%;\
    /let _len=$[strlen(_prefix)]%;\
    /let _match=%;\
;
;   scan list for words which start with prefix.
    /while ({#}) \
        /if (strncmp({1}, _prefix, _len) == 0) \
            /let _match=%{_match} %{1}%;\
        /endif%;\
        /shift%;\
    /done%;\
;
;   Remove duplicates (and strip leading space)
    /if (_need_unique) \
        /let _match=$(/unique %{_match})%;\
    /endif%;\
;   strip leading/trailing space
    /let _match=$[regmatch('^ *(.*?) *$', _match), {P1}]%;\
;
    /if (_match =~ "") \
;       No match was found.
        /beep 1%;\
    /elseif (_match !/ "{*}") \
;       Multiple matches were found.  Use longest common prefix.
        /beep 1%;\
        /@test input(substr($$(/common_prefix %%{_len} %%{_match}), _len))%;\
        /if (_match =~ _prev_match) \
	    /echo - %{_match}%;\
	/endif%; \
	/set _prev_match=%_match%; \
    /else \
;       Exactly one match was found.
        /@test _match := strcat(_match, _completion_suffix)%;\
        /if (_match =/ "*[A-Za-z0-9_]") \
            /@test _match := strcat(_match, " ")%;\
        /endif%;\
        /@test input(substr(_match, _len))%;\
    /endif%;\
;   Just to be safe
    /unset _completion_suffix%;\
    /unset _need_unique


/def -i complete_user_defined = \
    /_complete_from_list %1 %completion_list

/def -i ~input_history_list = \
    /let _input=$(/recall -i #1)%;\
    /recall -i 1-$[substr(_input, 0, strchr(_input, ":")) - 1]

/def -i complete_input_history = \
    /let _need_unique=1%;\
    /_complete_from_list %1 $(/~input_history_list)

/def -i complete_dynamic = \
    /let _need_unique=1%;\
    /_complete_from_list %1 %completion_list $(/~input_history_list)


/def -i complete_filename = \
    /quote -S /_complete_from_list $[filename({1})] !\
        echo `/bin/ls -dq $[filename({1})]* 2>/dev/null | \
            while read f; do \ test -d $$f && echo $$f/ || echo $$f; done`


/def -i complete_hostname = \
    /let _need_unique=1%;\
    /let _pf=$[substr({1}, strrchr({1}, "@") + 1)]%;\
    /quote -S /_complete_from_list %{_pf} !\
       echo `cat /etc/hosts %HOME/etc/hosts 2>/dev/null | \
          sed -n '/^[^#].*[ 	][ 	]*\\\\(%{_pf}[^ 	]*\\\\).*/s//\\\\1/p'`


/def -i complete_variable = \
    /let _part=$[substr({1}, strrchr({1}, '%') + 1)]%;\
    /if (strncmp(_part, '{', 1) == 0) \
        /let _part=$[substr(_part, 1)]%;\
        /let _completion_suffix=}%;\
    /endif%;\
    /_complete_from_list %_part $(/@listvar -s)


/def -i complete_macroname = \
    /let _word=%1%;\
    /let _i=$[strrchr({1}, '$')]%;\
    /if (_i >= 0) \
        /if (substr(_word, _i+1, 1) =~ '{') \
            /@test ++_i%;\
            /let _completion_suffix=}%;\
        /endif%;\
        /let _word=$[substr(_word, _i+1)]%;\
    /elseif (strncmp(_word, '/', 1) == 0) \
        /let _word=$[substr(_word, 1)]%;\
    /endif%;\
    /_complete_from_list %{_word} $(/quote -S /last `/@list -s -i - %{_word}*)


/def -i complete_worldname = \
    /_complete_from_list %1 $(/@listworlds -s %{1}*)

/def -i complete_sockname = \
    /_complete_from_list %1 $(/@listsockets -s %{1}*)


;; /complete_context <word>
;; Uses context to determine which completion macro to use.

/def -i complete_context = \
    /let _head=$[kbhead()]%;\
    /let _word=%1%;\
    /if (strchr(_word, "@") >= 0) \
        /complete_hostname %1%;\
    /elseif (strchr(_word, "%%") >= 0) \
        /complete_variable %1%;\
    /elseif (strchr(_word, "$$") >= 0) \
        /complete_macroname %1%;\
;   /elseif (_head =/ "{/*}") \
;       /complete_command %1%;\
    /elseif (_head =/ "{/*}") \
        /complete_macroname %1%;\
    /elseif (regmatch("-w(.+)$$", _head)) \
        /complete_worldname %P1%;\
    /elseif (_head =/ "*{/[sl]et|/setenv|/unset|/listvar|/edvar} {*}") \
        /complete_variable %1%;\
    /elseif (_head =/ "*{/load*|/save*|/lcd|/cd|/log} {*}") \
        /complete_filename %1%;\
    /elseif (_head =/ "*{/def|/edit|/edmac|/reedit|/undef|/list} {*}*") \
        /complete_macroname %1%;\
;   /elseif (_head =/ "{wh*|page|tel*|kill} {*}") \
;       /complete_playername %1%;\
    /elseif (regmatch(`/quote .*'("?)(.+)$$`, _head)) \
        /let _completion_suffix=%P1%;\
        /complete_filename %P2%;\
;   /elseif (regmatch('/quote .*`("?)(.+)$$', _head)) \
;       /let _completion_suffix=%P1%;\
;       /complete_command %P2%;\
    /elseif (regmatch('/quote .*`("?)(.+)$$', _head)) \
        /let _completion_suffix=%P1%;\
        /complete_macroname %P2%;\
    /elseif (_head =/ "*{/world|/connect|/edworld} {*}") \
        /complete_worldname %1%;\
    /elseif (_head =/ "*{/fg} {*}") \
        /complete_sockname %1%;\
    /elseif (_head =/ "*{/telnet} {*}") \
        /complete_hostname %1%;\
    /elseif (_head =/ "*/quote *!*") \
        /complete_filename %1%;\
    /elseif (_head =/ "*{/@test|/expr} *") \
        /complete_variable %1%;\
    /elseif (_head =/ "*{*/*|.*|tiny.*}") \
        /complete_filename %1%;\
    /else \
        /complete_dynamic %1%;\
    /endif


;;; /common_prefix <min> <list>...
;; prints the common prefix shared by each word in <list>, assuming at least
;; first <min> chars are already known to be shared.

/def -i common_prefix = \
    /let _min=%1%;\
    /shift%;\
    /let _prefix=%1%;\
    /let _len=$[strlen(_prefix)]%;\
    /while /shift%; /@test {#} & _len > _min%; /do \
        /let _i=%_min%;\
        /while (_i < _len & strncmp(_prefix, {1}, _i+1) == 0) \
            /@test ++_i%;\
        /done%;\
        /let _len=%_i%;\
    /done%;\
    /echo - $[substr(_prefix, 0, _len)]