#%TITLE% editfilename.MAC
#%NAME%
# Macros allowing to enter a filename with filename expansion.
#
#%CATEGORY% Tools
#
#%DESCRIPTION%
# This macro set allows to enter a filename with filename expansion.
#
#%LOG%
# $Revision: 1.4 $
# $Log: editfilename.mac,v $
# Revision 1.4 2008/02/27 17:12:55 rey
# documentation changes
#
# Revision 1.3 2008/02/27 17:12:12 rey
# documentation changs
#
#Revision 1.2 2007/08/09 16:15:57 witsch
#secure macros against existing macros coming with oscillation.mac
#Also there was a situation, where the path wouldn't be displayed
#correctly. This was due to lingering global variables, like "start".
#Secure these too. All variables and macros are now prefixed "_efn".
#
#Revision 1.1 2007/07/23 09:47:41 witsch
#Initial revision
#
##%END%
#%UU%(template)
#%MDESC% Enter a filename using filename expansion. %B%template%B% allows to
#preset a start directory (i.e. /data/id69).
def editfilename(template, max) '{
unglobal _EFN[]
global _EFN[]
_EFN["linebuffer"] = template == "" ? "/" : template
_EFN["cursorpos"] = length (_EFN["linebuffer"]) # place the cursor at end of line
# text might be longer than avaiable space
_EFN["start"] = 0; _EFN["currentpos"] = 0
_EFN["maxlength"] = max ? max : COLS
_efn_update_line
local c ; c = ""
while (c != "\n") {
# wait for charater to be typed, used char-by-char input mode (-1)
c = input (-1); while (asc(c) == 0) c = input (-1)
if (asc(c) == 27) _efn_escape_sequence
if (asc(c) == 8) _efn_delete_char
if (asc(c) == 127) _efn_delete_char
if (asc(c) >= 32 && asc(c) < 127) _efn_insert_char(c)
# if (asc(c) == 47) { c = 9; _EFN["linebuffer"] = _EFN["linebuffer"] "/" }
if (asc(c) == 21) {
_EFN["linebuffer"] = "/"
_EFN["cursorpos"] = 1
} else if (asc(c) == 9) {
global multiplechoice
unix(sprintf("ls -Adb %s* 2>/dev/null", _EFN["linebuffer"]), multiplechoice)
local aux[], many, len, i, dings, out
len = length(_EFN["linebuffer"]) + 1
many = split(multiplechoice, aux, "\n") - 1
delete aux[many] # last line always empty
unglobal multiplechoice
for (i = 0; i < many; i++) {
if (file_info(aux[i],"isdir")) {
aux[i] = aux[i] "/"
}
}
if (many == 1) {
_EFN["linebuffer"] = aux[0]
len = length(_EFN["linebuffer"]) + 1
_EFN["cursorpos"] = len - 1
out = 1
} else if (many == -1) { #nothing at all
out = 1
} else {
print
if (file_info(_EFN["linebuffer"],"isdir") && substr(_EFN["linebuffer"], len -1, 1) == "/") {
dings = "cd " _EFN["linebuffer"] "; ls 2>/dev/null"
} else {
dings = "cd $(dirname " _EFN["linebuffer"]
dings = dings "); ls -dbF $(basename " _EFN["linebuffer"] ")* 2>/dev/null"
}
unix(dings)
}
local firstc, followc
while(!out) { #now check how far the names agree
firstc = substr(aux[0], len, 1)
for (i = 1; i < many; i++) {
followc = substr(aux[i], len, 1)
if (followc != firstc) {
print
out=1
break
}
}
if (out) {
break
}
# this may only happen if all the members in aux have the
# same character in this position.
_EFN["linebuffer"] = _EFN["linebuffer"] firstc
len = length(_EFN["linebuffer"]) + 1
_EFN["cursorpos"] = len - 1
}
}
_efn_update_line
}
input (1) # back to line-by-line input mode (1)
unglobal multiplechoice
local retstr # get rid of all the global variables
retstr = _EFN["linebuffer"]
unglobal _EFN[]
return retstr
}'
#%IU%
#%MDESC% used by "editline" and "editfilename"
def _efn_insert_char(c) '{
part1 = substr (_EFN["linebuffer"],1,_EFN["cursorpos"])
part2 = substr (_EFN["linebuffer"],_EFN["cursorpos"]+1)
_EFN["linebuffer"] = part1 c part2 # concatenate strings
_EFN["cursorpos"]++
}'
#%IU%
#%MDESC% used by "editline" and "editfilename"
def _efn_update_line '{
_efn_scroll # make sure that cursor is within bounds
# relative cursor positioning is done by adding an offset of 1000 or -1000
tty_move(-1000-_EFN["currentpos"],1000)
local text; text = substr(_EFN["linebuffer"],_EFN["start"]+1,_EFN["maxlength"])
while (length(text) < _EFN["maxlength"]) text = text" " # pad with blanks
printf ("%s",text)
tty_move(-1000-length(text),1000)
tty_move(1000+_EFN["cursorpos"]-_EFN["start"],1000)
_EFN["currentpos"] = _EFN["cursorpos"]-_EFN["start"]
}'
#%IU%
#%MDESC% used by "editline" and "editfilename". Scroll text so cursor is within bounds
def _efn_scroll '{
if (_EFN["cursorpos"] >= _EFN["start"]+_EFN["maxlength"]) _EFN["start"] = _EFN["cursorpos"]-_EFN["maxlength"]+1;
if (_EFN["cursorpos"] < _EFN["start"]) _EFN["start"] = _EFN["cursorpos"];
}'
#%IU%
#%MDESC% used by "editline" and "editfilename". Decode VT100 escape sequences generated by the
# cursor keys
def _efn_escape_sequence '{
local c
# wait for end of escape-seqence (always with upper-case letter)
while (asc(c) < asc("A") || asc(c) > asc("Z")) c = input(-1)
if (c == "C") _efn_cursor_right
if (c == "D") _efn_cursor_left
# ignore all other escape-codes
}'
#%IU%
#%MDESC% used by "editline" and "editfilename"
def _efn_delete_char '{
if (_EFN["cursorpos"] > 0) {
part1 = substr (_EFN["linebuffer"],1,_EFN["cursorpos"]-1)
part2 = substr (_EFN["linebuffer"],_EFN["cursorpos"]+1)
_EFN["linebuffer"] = part1 part2 # concatenate strings
_EFN["cursorpos"]--
}
}'
#%IU%
#%MDESC% used by "editline" and "editfilename"
def _efn_cursor_right 'if (_EFN["cursorpos"] < length (_EFN["linebuffer"])) _EFN["cursorpos"]++'
#%IU%
#%MDESC% used by "editline" and "editfilename"
def _efn_cursor_left 'if (_EFN["cursorpos"] > 0) _EFN["cursorpos"]--'
#%MACROS%
#%NO_IMACROS%
#%AUTHOR% H. Witsch%BR%
# EDITFILENAME.MAC %BR%
#$Revision: 1.4 $, $Date: 2008/02/27 17:12:55 $
#%TOC%
|