home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / KEYBOARD / CMDED2E5.ZIP / EDIT.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-05-11  |  24.3 KB  |  980 lines

  1. ; EDIT.ASM
  2. ; (c) 1989, 1990 Ashok P. Nadkarni
  3. ;
  4. ; This module contains the line editing functions of CMDEDIT.
  5. ; ^T function (macro disable toggle)  added by dfa,  December 1990.
  6. ; Ability to switch ESC to filename completion added by dfa, May 1991.
  7.  
  8.     PUBLIC    get_kbd_line
  9.     PUBLIC    auto_recall
  10.     PUBLIC    expand_fnkey
  11.     PUBLIC  ESC_key_function     ;Added by dfa
  12.     PUBLIC  TAB_key_function     ;Added by dfa
  13.  
  14.     INCLUDE common.inc
  15.     INCLUDE ascii.inc
  16.     INCLUDE    BIOS.INC
  17.     INCLUDE    DOS.INC
  18.     INCLUDE    GENERAL.INC
  19.  
  20.  
  21. CSEG    SEGMENT    PARA PUBLIC 'CODE'
  22. CSEG    ENDS
  23.  
  24. DGROUP    GROUP    CSEG
  25.  
  26.     ASSUME    CS:DGROUP, DS:DGROUP, SS:DGROUP, ES:DGROUP
  27.  
  28. CSEG    SEGMENT    PARA PUBLIC 'CODE'
  29.  
  30.     EXTRN    linebuf:BYTE
  31.     EXTRN    lastchar:WORD
  32.     EXTRN    caller_cursor:WORD
  33.     EXTRN    dot:WORD
  34.     EXTRN    edit_mode:BYTE
  35.     EXTRN    omode_cursor:WORD
  36.     EXTRN   disable_macro:BYTE   ;added by dfa
  37.     EXTRN    sym_stk:WORD
  38.     EXTRN    LINEBUF_END:ABS
  39.  
  40.  
  41. tempchar db    ?            ;Temporary storage
  42. auto_recall    db    0        ;By default no auto recall
  43. auto_recall_on    db    ?        ;1 if auto-recall in effect,
  44. ;                     else 0
  45. continue_recall db    ?        ;auto-recall state variable
  46. fnkey_tab    db    'S','F',0    ;Used to look for function key
  47. ;                     definitions. 
  48. fnkey_exec_char db    '@'        ;If the last character a fn key
  49. ;                     definition is this, the key is
  50. ;                     executed immediately
  51.  
  52. ; Must be IDENTICAL to the string in CMDCONF.C including the
  53. ; terminating '\0' byte. This must be followed immediately by ctrl_key_defs.
  54. cmdedit_keymap_id db    'CMDEDIT key map',0
  55. ; ctrl_key_redefs is used to allow the cmdconf program to remap the control
  56. ; keys. Each entry corresponds to a control key. It must immediately follow
  57. ; cmdedit_keymap_id.
  58. ctrl_key_redefs LABEL WORD
  59. x    =    0
  60.     REPT    32                ;32 control keys
  61.     DW    x
  62. x    =    x + 1
  63.     ENDM
  64.  
  65.  
  66.     EXTRN    disp_line:PROC
  67.     EXTRN    hist_back:PROC
  68.     EXTRN    hist_fwd:PROC
  69.     EXTRN    hist_bck_match:PROC
  70.     EXTRN    hist_fwd_match:PROC
  71.     EXTRN    remember:PROC
  72.     EXTRN    execute_auto_recall:PROC
  73.     EXTRN    insert_at_dot:PROC
  74.     EXTRN    erase_to_dot:PROC
  75.     EXTRN    isalphnum:PROC
  76.     EXTRN    set_disp_marks:PROC
  77.     EXTRN    bell:PROC
  78.     EXTRN    line_to_scr:PROC
  79.     EXTRN    isspace:PROC
  80.     EXTRN    xlate_lower:PROC
  81.     EXTRN    expand_var:PROC
  82.     EXTRN    ismacsym:PROC
  83.     EXTRN    get_symbol:PROC
  84.     
  85. ;number of command keys
  86. NUM_CMD_KEYS    EQU    (cmd_key_jumps-cmd_key_table)/2
  87.  
  88. ;+
  89. ; FUNCTION : get_kbd_line
  90. ;
  91. ;    Gets a line from the user and stores it in linebuf. The length
  92. ;    of the line is stored in global linelen. The name is a misnomer
  93. ;    because the line is from standard input, not necessarily from
  94. ;    the keyboard.
  95. ;
  96. ; Parameters:
  97. ;    None.
  98. ;
  99. ; Returns:
  100. ;    Nothing.
  101. ; Register(s) destroyed:
  102. ;-
  103.  
  104. get_kbd_line    proc    near
  105.     @save    si,di
  106.     mov    al,auto_recall
  107.     mov    auto_recall_on,al    ;Indicate if auto-recall is enabled
  108.     mov    continue_recall,1    ;Init auto-recall memory
  109.  
  110. ; Main editing loop
  111. @get_kbd_line_10:
  112.     mov    al,continue_recall
  113.     and    auto_recall_on,al    ;Indicate if we should keep
  114. ;                     auto-recalling
  115.     mov    continue_recall,0    ;Reset the flag. It will be set
  116. ;                     for the default actions keys.
  117.     call    near ptr disp_line    ;Show current line
  118.     call    near ptr getkey        ;get next key from the user
  119.     mov    si,ax            ;si holds the character
  120.     cmp    ax,32            ;Control character ?
  121.     jge    @get_kbd_line_15    ;No, then check if fn key
  122.     mov    di,si            ;DI used to calculate
  123.     add    di,di            ;  offset into table
  124.     mov    ax,ctrl_key_redefs[di]    ;Mapping of key
  125.     mov    si,ax
  126.     cmp    ax,32            ;Control char ?
  127.     jge    @get_kbd_line_15    ;No, then check if fn key
  128.     mov    di,si            ;DI used to calculate
  129.     add    di,di            ;  offset into table
  130.     jmp    ctrl_key_table[di]    ;Branch according to control char
  131. @get_kbd_line_15:            ;Check if function key
  132.     cmp    ax,256+59        ;>= F1 ?
  133.     jb    @get_kbd_line_20    ;No, then check next table
  134.     cmp    ax,256+68        ;<= F10
  135.     jg    @get_kbd_line_20    ;Not fn key
  136.     jmp    @fn_key            ;Handle the function key
  137. @get_kbd_line_20:
  138.     cmp    ax,256+84        ;>= Shift-F1 ?
  139.     jb    @get_kbd_line_25    ;No, then check next table
  140.     cmp    ax,256+93        ;<= Shift-F10
  141.     jg    @get_kbd_line_25    ;
  142.     jmp    @sfn_key        ;Handle the shifted function key
  143. @get_kbd_line_25:
  144.     mov    cx,NUM_CMD_KEYS        ;size and...
  145.     mov    bx,offset DGROUP:cmd_key_table    ;beginning of jump table
  146. @get_kbd_line_30:            ;Loop begin
  147.     cmp    ax,cs:[bx]        ;Is this the key ?
  148.     je    @get_kbd_line_40    ;Hurrah, found
  149.     inc    bx            ;point to next key
  150.     inc    bx
  151.     loop    @get_kbd_line_30    ;If more keys, repeat
  152.     jmp    short @default_action    ;key not in table
  153. @get_kbd_line_40:            ;Jump to location associated with
  154.     jmp    word ptr cs:[bx+(2*NUM_CMD_KEYS)]    ;key
  155.  
  156. @quote:                    ;Insert next char
  157. ;                     without interpreting it
  158.     call    near ptr  getkey
  159.  
  160. @default_action:            ;Insert the character (in AX)
  161.     call    near ptr store_char
  162.     jc    @get_kbd_line_10    ;No room for char, keep looping
  163.     mov    al,auto_recall_on    ;Are we auto-recalling ?
  164.     or    al,al
  165.     jz    @get_kbd_line_10    ;No
  166.     call    near ptr execute_auto_recall
  167.     jc    @get_kbd_line_10    ;If carry set, no matching
  168. ;                     string in history buffer
  169.     mov    continue_recall,1    ;Else indicate auto-recall is
  170. ;                     still to go on
  171.     jmp    short @get_kbd_line_10
  172.  
  173.  
  174. @char_left:                ;Cursor one char left
  175.     call    near ptr char_left    ;char_left will return to top
  176.     jmp    @get_kbd_line_10
  177. ;                     of editing loop
  178.  
  179. @char_right:                ;Cursor one char right
  180.     call    near ptr char_right    ;char_right will return to top
  181.     jmp    @get_kbd_line_10
  182. ;                     of editing loop
  183.  
  184. @word_left:                ;Cursor one word left
  185.     call    near ptr word_left
  186.     jmp    @get_kbd_line_10
  187.  
  188. @word_right:                ;Cursor one word right
  189.     call    near ptr word_right
  190.     jmp    @get_kbd_line_10
  191.  
  192. @bol:                    ;Beginning of line
  193.     call    near ptr go_bol
  194.     jmp    @get_kbd_line_10
  195.  
  196.  
  197. @eol:                    ;End of line
  198.     call    near ptr go_eol
  199.     jmp    @get_kbd_line_10
  200.  
  201.  
  202. @prev_line:                ;Get previous history line
  203.     mov    ax,offset DGROUP:hist_back
  204. @history_line:
  205.     call    ax
  206.     mov    ax,lastchar
  207.     mov    dot,ax            ;Leave cursor at end of line
  208. @history_search:
  209.     jnc    @history_line_done    ;Line found
  210.     call    near ptr bell        ;No line
  211. @history_line_done:
  212.     jmp    @get_kbd_line_10
  213.  
  214. @next_line:                ;Get next history line
  215.     mov    ax,offset DGROUP:hist_fwd
  216.     jmp    short @history_line
  217.  
  218. @search_back:                ;Search back thru history buffer
  219.     mov    ax,offset DGROUP:hist_bck_match
  220. @search:
  221.     mov    di,dot            ;Save current dot
  222.     call    ax
  223.     mov    dot,di            ;Restore it
  224.     jmp    short @history_search
  225.  
  226. @search_forw:                ;Search forward thru history buffer
  227.     mov    ax,offset DGROUP:hist_fwd_match
  228.     jmp    short @search
  229.  
  230. @filename:                ;Try to find a matching filename
  231.     call    near ptr match_file
  232.     cmp    auto_recall_on,1    ;Autorecall ongoing?
  233.     je    short @del_eol        ;Yes, then delete to end of line
  234.     jmp    @get_kbd_line_10
  235.  
  236. @del_left:                ;Delete char before cursor
  237.     mov    ax,offset dgroup:char_left
  238.     jmp    short @delete
  239.  
  240. @del_right:                ;Delete char at cursor
  241.     mov    ax,offset dgroup:char_right
  242.     jmp    short @delete
  243.  
  244.  
  245. @del_prev_word:                ;Delete upto word beginning
  246.     mov    ax,offset dgroup:word_left
  247.     jmp    short @delete
  248.  
  249. @del_next_word:                ;Delete to start of next word
  250.     mov    ax,offset dgroup:word_right
  251.     jmp    short @delete
  252.  
  253. @del_bol:                ;Delete to beginning of line
  254.     mov    ax,offset dgroup:go_bol
  255.     jmp    short @delete
  256.  
  257.  
  258. @toggle_insert:
  259.     mov    ax,1
  260.     xor    al,edit_mode        ;Toggle edit mode
  261.     mov    edit_mode,al
  262.     xchg    ax,bx
  263.     add    bx,bx            ;Word offset
  264.     mov    cx,omode_cursor[bx]    ;cx<-cursor shape
  265.     mov    ah,01h            ;Set cursor size function
  266.     IF    TOGGLE_CURSOR
  267.     int    10h            ;BIOS 
  268.     ENDIF
  269.     jmp    @get_kbd_line_10    ;Repeat editing loop
  270.  
  271. @abort_and_store:            ;Erases current line but remembers
  272. ;                     it in the history buffer
  273.     call    near ptr remember
  274. ;    Fall through to erase line
  275. @erase_line:
  276.     call    near ptr go_bol        ;Move dot to beginning of line
  277. ;    fall thru to delete to end of line
  278.  
  279. @del_eol:                ;Delete to end of line
  280.     mov    ax,offset dgroup:go_eol
  281.  
  282. @delete:                ;General purpose delete
  283.     mov    si,dot            ;Remember the dot
  284.     call    ax            ;Move dot to new position
  285.     xchg    si,ax
  286.     call    near ptr erase_to_dot    ;Delete characters between ax and dot
  287.     jmp    @get_kbd_line_10
  288.  
  289. @autorecall:
  290.     xor    auto_recall,1        ;Toggle auto recall mode
  291.     jmp    @get_kbd_line_10
  292.  
  293. @macro:   ;added by dfa
  294.     xor disable_macro,1       ;Toggle macro & symbol expansion disable
  295.     jmp @get_kbd_line_10
  296.  
  297.  
  298. @vars:
  299. ; Expand the variables on the line.
  300.     call    near ptr expand_var
  301.     jmp    @get_kbd_line_10    ;Ignore return status from expand_var
  302.  
  303.  
  304. @inline_back:
  305. @inline_forw:
  306. @ignore:
  307.     jmp    @get_kbd_line_10    ;Ignore the character
  308.  
  309.  
  310. ctrl_key_table    LABEL    WORD
  311.     dw    @ignore        ;NUL or ^@
  312.     dw    @bol        ;^A
  313.     dw    @char_left    ;^B
  314.     dw    @ignore        ;^C
  315.     dw    @del_right    ;^D
  316.     dw    @eol        ;^E
  317.     dw    @char_right    ;^F
  318.     dw    @abort_and_store ;^G
  319.     dw    @del_left    ;^H
  320. TAB_key_function dw  @filename   ;^I   ( label added by dfa )
  321.     dw    @vars        ;^J might have to be @ignore in order for input 
  322. ;                 redirection to work properly but try for
  323. ;                 var expansion anyway.
  324.     dw    @del_eol    ;^K
  325.     dw    @del_prev_word    ;^L
  326.     dw    @done_editing    ;^M
  327.     dw    @next_line    ;^N
  328.     dw    @del_eol_exec    ;^O
  329.     dw    @ignore        ;^P - don't use, filtered by get key call ?
  330.     dw    @quote        ;^Q
  331.     dw    @search_back    ;^R
  332.     dw    @ignore        ;^S - don't use, does not work properly
  333.     dw  @macro      ;^T  (changed by dfa - was @ignore)
  334.     dw    @prev_line    ;^U
  335.     dw    @search_forw    ;^V
  336.     dw    @del_next_word    ;^W
  337.     dw    @del_bol    ;^X
  338.     dw    @autorecall    ;^Y
  339.     dw    @default_action    ;^Z
  340. ESC_key_function dw  @erase_line ;^[ or ESC   (label added by dfa)
  341.     dw    @inline_back    ;^\
  342.     dw    @inline_forw    ;^]
  343.     dw    @done_wipeout    ;^^
  344.     dw    @ignore        ;^_
  345.  
  346. cmd_key_table:                ;table of command keys
  347.     dw    127    ;DEL
  348.     dw    327    ;HOME
  349.     dw    328    ;UP
  350.     dw    331    ;LEFT
  351.     dw    333    ;RIGHT
  352.     dw    335    ;END
  353.     dw    336    ;DOWN
  354.     dw    338    ;INS
  355.     dw    339    ;KDEL
  356.     dw    371    ;CTLLEFT
  357.     dw    372    ;CTLRIGHT
  358. cmd_key_jumps:
  359.     dw    @del_left    ;DEL
  360.     dw    @bol        ;HOME
  361.     dw    @prev_line    ;UP
  362.     dw    @char_left    ;LEFT
  363.     dw    @char_right    ;RIGHT
  364.     dw    @eol        ;END
  365.     dw    @next_line    ;DOWN
  366.     dw    @toggle_insert    ;INS
  367.     dw    @del_right    ;KDEL
  368.     dw    @word_left    ;CTLLEFT
  369.     dw    @word_right    ;CTLRIGHT
  370.  
  371.  
  372. @sfn_key:
  373. ; A shifted function key has been struck.
  374. ; (Treat same as an unshifted function key).
  375. @fn_key:
  376. ; A function key has been struck.
  377.     call    near ptr expand_fnkey
  378.     jc    @fn_key_20            ;Error or no expansion
  379.     or    dx,dx                ;Line to be executed
  380. ;                         immediately ?
  381.     je    short @done_editing_2        ;Yes, all done
  382. @fn_key_20:
  383.     jmp    @get_kbd_line_10        ;else keep editing
  384.  
  385. @del_eol_exec:                ;Deletes characters from the dot
  386. ;                     to end of the line and then
  387. ;                     executes the line
  388.     mov    si,dot            ;Remember the dot
  389.     call    go_eol
  390.     xchg    si,ax
  391.     call    near ptr erase_to_dot
  392.     jmp    short @done_editing
  393.  
  394.  
  395. @done_wipeout:
  396. ; The line is executed. However it is not stored in the history buffer and
  397. ; is also removed from the screen (this is a little klugy).
  398.     mov    ax,offset DGROUP:linebuf
  399.     mov    dot,ax
  400.     mov    dx,lastchar
  401.     mov    lastchar,ax            ;Temporarily pretend line
  402. ;                         is empty
  403.     xchg    ax,dx
  404.     push    ax
  405.     call    near ptr set_disp_marks
  406.     call    disp_line
  407.     pop    ax
  408.     mov    lastchar,ax            ;Restore line length
  409.     jmp    short @get_kbd_line_90
  410.  
  411. @done_editing:
  412.     call    near ptr remember    ;Store in history buffer
  413. ;                     Picks up line from global linebuf
  414. @done_editing_2:
  415.     call    near ptr disp_line    ;Necessry for @del_eol_exec,
  416. ;                     might as well do for others
  417.     mov    ax,lastchar
  418.     mov    dot,ax            ;Set dot to end of line
  419.     call    near ptr line_to_scr    ;Set cursor beyond last character
  420.  
  421. @get_kbd_line_90:
  422.     @DispCh CR            ;Do a carraige return because
  423. ;                     some applications like EDLIN
  424. ;                     only do a LF to go to next line
  425. ;    @DispCh LF            ;Go onto next line
  426. ;    all done
  427. @get_kbd_line_99:
  428.     @restore
  429.     ret
  430. get_kbd_line endp
  431.  
  432.  
  433.  
  434. getkey proc near
  435.     @GetKey    0
  436.     mov    ah,0
  437.     or    al,al
  438.     jne    @114        ;not '\0'
  439.     mov    ah,0Bh
  440.     int    21h        ;check if key available
  441.     or    al,al
  442.     jz    @113        ;no character available
  443.     @GetKey    0
  444.     mov    ah,1
  445.     jmp    short @114
  446. @113:
  447.     xor    ax,ax
  448. @114:
  449.     ret
  450. getkey    endp
  451.  
  452.  
  453.  
  454. ;+
  455. ; FUNCTION : expand_fnkey
  456. ;
  457. ;    Inserts the expansion corresponding to a symbol key into the
  458. ;    linebuffer. If the buffer is too small, only as many characters as
  459. ;    possible are inserted and the function returns an error. The
  460. ;    function also returns an error if the symbols is not defined. The
  461. ;    function also updates the displayed line. The function also checks
  462. ;    if the line is to be executed immediately or not, based on the last
  463. ;    character of the fn key expansion.
  464. ;
  465. ; Parameters:
  466. ;    AX    = function key character, must be between (256+59)-(256+68)
  467. ;          function keys and (256+84)-(256+93) for shifted functin keys.
  468. ;
  469. ; Returns:
  470. ;    CF    = 0 if no error, else 1
  471. ;          If CF is 1, then AX is 0 if symbol not found or non-zero
  472. ;          if symbol found but no room in line.
  473. ;    AX    = 1 if symbol was present 
  474. ;          0 if symbol was not found.
  475. ;    DX    = 0 if the line is to be executed immediately
  476. ;          non-0 otherwise
  477. ;          DX is only valid if CF=0 and AX=1
  478. ; Register(s) destroyed:
  479. ;     <TBA>
  480. ;-
  481. expand_fnkey proc near
  482.     @save    si,di
  483.     push    bp
  484.     mov    bp,sp
  485.     sub    sp,LINEBUF_SIZE
  486. exp_buf    equ <byte ptr [bp-LINEBUF_SIZE]>
  487.  
  488.     mov    si,offset DGROUP:fnkey_tab    ;SI->'SFn'
  489.     mov    dx,3                ;DX<-length of string
  490.     mov    di,si
  491.     sub    ax,256+59
  492.     cmp    ax,10                ;Is it a function key
  493.     jnb    @expand_fnkey_10        ;No, shifted function key
  494.     inc    si                ;SI->'Fn'
  495.     dec    dx                ;length of string is 2
  496.     jmp    short @expand_fnkey_15
  497. @expand_fnkey_10:
  498.     sub    ax,84-59
  499. @expand_fnkey_15:
  500.     cmp    ax,9                ;F10 must appear as F0
  501.     jne    @expand_fnkey_20
  502.     mov    al,'0'-'1'
  503. @expand_fnkey_20:
  504.     add    al,'1'
  505.     mov    2[di],al            ;Store in 'SFn' string
  506. ; OK now try and expand the symbol.
  507. ;                         SI->symbol
  508.     mov    ax,LINEBUF_SIZE
  509.     xchg    ax,dx                ;AX<-length of synbol
  510. ;                         DX<-length of expansion buffer
  511.     lea    di,exp_buf
  512.     call    near ptr get_symbol        ;Params SI,AX,DI,DX
  513.     jc    @expand_fnkey_99        ;No symbol (buffer too
  514. ;                         small case not possible).
  515. ;                         AX will be 0 for this case.
  516. ; OK now we have the symbol expansion, so try insert it into the linebuffer.
  517. ;    AX contains length of expansion
  518.     mov    si,di                ;SI->expansion
  519.     add    di,ax
  520.     dec    di                ;DI->last char of expansion
  521.     xor    dx,dx
  522.     mov    dl,byte ptr [di]        
  523.     sub    dl,fnkey_exec_char        ;Is this line to be
  524. ;                         immediately executed
  525.     jne    @expand_fnkey_80        ;No
  526.     dec    ax                ;The last char of expansion
  527. ;                         is a special char. Do not
  528. ;                         include it in the insert
  529. ;                         string 
  530. @expand_fnkey_80:
  531.     push    dx
  532.     call    near ptr insert_at_dot        ;Params SI,AX
  533. ;    pushf                    ;Save CF
  534. ;    call    disp_line
  535. ;    popf                    ;Restore CF
  536.     mov    ax,1                ;AX<-exit code
  537.     pop    dx                ;DX is 0 if line is to be
  538. ;                         executed immediately
  539. @expand_fnkey_99:
  540.     mov    sp,bp
  541.     pop    bp
  542.     @restore
  543.     ret
  544.  
  545. expand_fnkey endp
  546.  
  547.  
  548. ;+
  549. ; FUNCTION : store_char
  550. ;
  551. ;    Stores    the character in AX into the line buffer if max line
  552. ;    length will not be exceeded. Characters may be inserted or
  553. ;    overwrite chars in the buffer depending on the edit mode and whether
  554. ;    auto-recall is on.
  555. ;
  556. ; Parameters:
  557. ;    AX    = character
  558. ;
  559. ; Returns:
  560. ;    CF    = 0 if no error, else 1
  561. ; Register(s) destroyed:
  562. ;     <TBA>
  563. ;-
  564. store_char proc near
  565.     @save    si
  566.     cmp    ax,256            ;char >= 256
  567.     jnb    @store_char_90        ;Ignore if so
  568.     cmp    edit_mode,0        ;1 if insert mode
  569.     je    @store_char_20        ;Jump if overtype mode
  570.     cmp    auto_recall_on,1    ;Is auto-recall on ?
  571.     je    @store_char_20        ;Yes, behave as if in overtype mode
  572.     mov    si,offset dgroup:tempchar ;temporary storage
  573.     mov    [si],al            ;Store char
  574.     mov    ax,1            ;Length of string
  575.     call    near ptr insert_at_dot    ;Insert the character
  576.     jnc    @store_char_99        ;No problemo
  577.     jmp    short @store_char_90    ;No room in buffer
  578. @store_char_20:
  579.     mov    si,dot            ;Current position in line
  580.     cmp    si,LINEBUF_END        ;At line end?
  581.     jae    @store_char_90
  582. ;    Enough room for a char
  583.     mov    [si],al            ;Store the char
  584.     mov    dx,si            ;DX->changed character
  585.     mov    ax,si
  586.     inc    ax            ;AX->char after change
  587.     mov    dot,ax            ;Store it as new dot position
  588.     cmp    si,lastchar        ;Was it end of line ?
  589.     jb    @store_char_30
  590.     mov    lastchar,ax        ;Store new end of line
  591. @store_char_30:
  592.     call    near ptr set_disp_marks    ;ax,dx parameters
  593.     clc                ;Indicate no error
  594.     jmp    short @store_char_99
  595. @store_char_90:
  596.     call    near ptr bell
  597.     stc                ;Indicate error
  598. @store_char_99:
  599.     @restore
  600.     ret
  601. store_char endp
  602.  
  603.  
  604. ;+
  605. ; FUNCTION : word_left
  606. ;
  607. ;    Move one word left.
  608. ;
  609. ; Parameters:
  610. ;    Globals linebuf and dot.
  611. ;
  612. ; Returns:
  613. ;    CF = 1 if dot was at beginning of the line already
  614. ;         0 otherwise.
  615. ; Register(s) destroyed:
  616. ;-
  617. word_left proc near
  618. @word_left_10:
  619.     call    near ptr char_left    ;Move one char left
  620.     jc    @word_left_99        ;Already at beginning of line
  621. @word_left_12:
  622.     ;Loop to backup over non-alphanum
  623.     call    near ptr isalphnum    ;AL alphanumeric?
  624.     jnc    @word_left_15        ;Yes
  625.     call    near ptr char_left    ;One char left.
  626.                     ;AL<-char at dot
  627.     jnc    @word_left_12        ;Not at beginning of line
  628. @word_left_15:                ;Now backup to beginning of word
  629. ;    At this point, dot is always at a alphabetic char or beginning
  630. ;    of the line
  631.     call    near ptr char_left
  632.     jc    @word_left_98        ;Were already at beginning of line
  633.     call    near ptr isalphnum    ;Alphanumeric?
  634.     jnc    @word_left_15        ;Yes, loop back
  635.                     ;Found non-alphanumeric char
  636.     call    near ptr char_right    ;move over one
  637. @word_left_98:
  638.     clc                ;Clear carry flag
  639. @word_left_99:
  640.     ret
  641. word_left endp
  642.  
  643.  
  644.  
  645. ;+
  646. ; FUNCTION : word_right
  647. ;
  648. ;    Move one word right.
  649. ;
  650. ; Parameters:
  651. ;    Globals linebuf and dot.
  652. ;
  653. ; Returns:
  654. ;    Nothing.
  655. ; Register(s) destroyed:
  656. ;-
  657. word_right proc near
  658. @word_right_10:                ;Loop fwd over alphanumerics
  659.     call    near ptr char_right    ;One char right
  660.                     ;AL<-char at dot
  661.     jc    @word_right_99        ;Already at end of line
  662.     call    near ptr isalphnum    ;Is AL alphanumeric ?
  663.     jnc    @word_right_10        ;Yes, loop back
  664. @word_right_15:                ;Now move to beginning of word
  665.     call    near ptr char_right
  666.     jc    @word_right_99        ;Already at end of line
  667.     call    near ptr isalphnum    ;Alphanumeric?
  668.     jc    @word_right_15        ;Not alphanum char, loop back
  669. @word_right_99:
  670.     ret
  671. word_right endp
  672.  
  673.  
  674.  
  675.  
  676. ;+
  677. ; FUNCTION : char_left
  678. ;
  679. ;    Moves the 'dot' one character to the left unless
  680. ;    already at the beginning of the line.
  681. ;
  682. ; Parameters:
  683. ;    Global    dot is current position in the line.
  684. ;
  685. ; Returns:
  686. ;    AL    = char at new dot position.
  687. ;    CF    = 1 if OLD dot was at beginning of line
  688. ;          0 otherwise.
  689. ; Register(s) destroyed:
  690. ;-
  691. char_left proc    near
  692.     @save    si
  693.     mov    ax,dot            ;Current position in line
  694.     cmp    ax,offset dgroup:linebuf
  695.     jne    @char_left_5
  696.     stc                ;Dot already at beginning of line
  697.     jmp    short @char_left_99
  698. @char_left_5:
  699.     dec    ax            ;Move dot left
  700.     mov    dot,ax
  701. @char_left_99:
  702.     xchg    ax,si
  703.     lodsb                ;AL<-char at dot
  704.     @restore
  705.     ret
  706. char_left endp
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714. ;+
  715. ; FUNCTION : char_right
  716. ;
  717. ;    Moves the 'dot' one character to the right unless
  718. ;    already at the end of the line.
  719. ;
  720. ; Parameters:
  721. ;    Global    dot is current position in the line.
  722. ;
  723. ; Returns:
  724. ;    AL    = char at new dot position. Undefined if new dot is at
  725. ;          the end of the line.
  726. ;    CF    = 1 if OLD dot was already at end of the line.
  727. ;          0 otherwise.
  728. ; Register(s) destroyed:
  729. ;-
  730. char_right proc    near
  731.     @save    si
  732.     mov    si,dot            ;Current position in line
  733.     mov    ax,lastchar        ;AX->Beyond last char
  734.     dec    ax            ;AX->last char in line
  735.     cmp    ax,si            ;Dot at end ?
  736.     jc    @char_right_99        ;Already at line end
  737.     inc    si            ;Move dot right, CF not affected
  738.     mov    dot,si
  739.     lodsb                ;AL<-char at dot, (undefined if
  740. ;                     dot is now at end of line).
  741. ;    CF    already clear
  742. @char_right_99:
  743.     @restore
  744.     ret
  745. char_right endp
  746.  
  747.  
  748.  
  749. ;+
  750. ; FUNCTION : go_bol
  751. ;
  752. ;    Sets    dot to pint to the beginning of the line
  753. ;
  754. ; Register(s) destroyed: None.
  755. ;-
  756. go_bol    proc    near
  757.     mov    dot,offset dgroup:linebuf
  758.     ret
  759. go_bol    endp
  760.  
  761.  
  762.  
  763. ;+
  764. ; FUNCTION : go_eol
  765. ;
  766. ;    Sets    dot to pint to the end of the line
  767. ;
  768. ; Register(s) destroyed: AX.
  769. ;-
  770. go_eol    proc    near
  771.     mov    ax,lastchar
  772.     mov    dot,ax
  773.     ret
  774. go_eol    endp
  775.  
  776.  
  777.  
  778.  
  779. ;+
  780. ; FUNCTION : match_file
  781. ;
  782. ;    match_file tries to expand the filename to the left of the
  783. ;    cursor. If there are several matching files, the longest common
  784. ;    prefix is placed on the line.
  785. ;
  786. ; Parameters:
  787. ;    None.
  788. ;
  789. ; Returns:
  790. ;    Nothing.
  791. ; Register(s) destroyed:
  792. ;-
  793. match_file proc    near
  794.     @save    si,di
  795.     push    bp
  796.     mov    bp,sp
  797.     sub    sp,64+44+2+2+2+2+2+2    ;Locals
  798. pname        equ    64        ;Storage for entire filename with path
  799. ffblk        equ    pname+44
  800. ffblk_attr     equ    ffblk-15h    ;Attr byte within ffblk
  801. ffblk_name     equ    ffblk-1Eh    ;filename within ffblk
  802. fname        equ    ffblk+2        ;Points to start of filename in name
  803. oldDTAseg     equ    fname+2
  804. oldDTAoff     equ    oldDTAseg+2
  805. lineptr        equ    oldDTAoff+2    ;Pointer to location in linebuf    
  806. remaining    equ    lineptr+2    ;Remembers remaining space in path
  807. breakstate    equ    remaining+2    ;Remembers break state
  808.  
  809.     mov    ax,3300h        ;Get current break state
  810.     int    21h            ;DL<-current break state
  811.     mov    byte ptr [bp-breakstate],dl ;Remember it
  812.     xor    dl,dl
  813.     mov    ax,3301h        ;Disable break check during
  814. ;                     disk i/O
  815.     int    21h
  816.     lea    di,[bp-pname]        ;OK 'cause SS==DS
  817.     mov    si,dot            ;Current line position
  818.     mov    cx,63            ;Max length of path
  819. @match_file_10:
  820.     cmp    si,offset dgroup:linebuf
  821.     je    @match_file_51        ;Beginning of line and filename
  822.     dec    si
  823.     mov    al,[si]            ;AL<-next char
  824. @match_file_25:
  825.     call    near ptr isspace
  826.     je    @match_file_50        ;Beginning of filename
  827. @match_file_45:                ;Check for next char if
  828. ;                     pathname not too long
  829.     loop    @match_file_10
  830.     jmp    @match_file_99        ;Pathname too long, just exit
  831. @match_file_50:
  832.     inc    si
  833. @match_file_51:
  834. ;    Copy    filename into ASCIIZ buffer
  835. ;    SI->first char of filename in path buffer
  836.     xor    dx,dx            ;Flags
  837.     mov    ax,63
  838.     sub    ax,cx            ;Length of name
  839.     mov    [bp-remaining],cx    ;remember num bytes left in
  840. ;                     path buffer
  841.     xchg    ax,cx            ;CX<-length of name
  842.     mov    [bp-lineptr],si        ;Save start of path name in linebuf
  843.     mov    [bp-fname],di        ;Remember start of filename in
  844. ;                     path buffer as well (assumed)
  845.     or    cx,cx            ;Too far for jcxz
  846.     jne    @match_file_55
  847.     jmp    @match_file_99        ;No name, just exit
  848. @match_file_55:
  849.     lodsb                ;AL<-next char
  850.     stosb                ;Store it
  851.     cmp    al,'.'
  852.     jne    @match_file_56
  853.     or    dl,1            ;Set flag to remember file type '.'
  854.     jmp    short @match_file_65    ;Check out next character
  855. @match_file_56:
  856.     cmp    al,'\'            ;Directory separator?
  857.     jne    @match_file_59
  858. @match_file_57:
  859.     mov    [bp-fname],di        ;Update start of filename in
  860. ;                     path buffer
  861. @match_file_58:
  862.     and    dl,0FEh            ;Forget file type flag
  863.     jmp    short @match_file_65
  864. @match_file_59:
  865.     cmp    al,'/'            ;Same thing
  866.     je    @match_file_57
  867.     cmp    al,':'            ;Disk?
  868.     jne    @match_file_65
  869.     and    dl,0FEh            ;Forget file type (shouldn't really 
  870. ;                     occur)
  871.     mov    [bp-fname],di        ;Update start of filename in
  872. ;                     path buffer
  873.  
  874. @match_file_65:
  875.     loop    @match_file_55
  876.  
  877.     mov    cx,[bp-remaining]    ;CX<-remaining space
  878.     jcxz    @match_file_52        ;Only space for terminator
  879.     mov    al,'*'
  880.     stosb                ;Attach a '*'
  881.     cmp    cl,3            ;Enough space for ".*"
  882.     jb    @match_file_52
  883.     and    dl,1            ;Saw a file type ?
  884.     jne    @match_file_52        ;Yes, go attach terminator
  885.     mov    [di],2A2Eh        ;Attach a ".*"
  886.     inc    di
  887.     inc    di
  888. @match_file_52:
  889.     xor    al,al            ;AL<-0
  890.     stosb                ;Terminating 0
  891.  
  892. ;    name    contains the filename
  893.     push    es
  894.     @GetDTA                ;Get and save old DTA
  895.     mov    [bp-oldDTAseg],es
  896.     mov    [bp-oldDTAoff],bx
  897.     pop    es
  898. ;
  899.     lea    dx,[bp-ffblk]
  900.     @SetDTA    dx            ;Set DTA to our DTA
  901.  
  902.     lea    dx,[bp-pname]        ;dx->ASCII name
  903.     @GetFirst dx,16            ;Include subdirs in search
  904.     jnc    @match_file_70        ;No error
  905.     call    near ptr bell        ;No files found
  906.     jmp    @match_file_90        ;Restore DTA and exit 
  907.  
  908.  
  909. @match_file_70:                ;At least one file found
  910.     mov    di,[bp-fname]        ;DI->filename portion
  911.     lea    si,[bp-ffblk_name]    ;Name returned by GetFirst
  912. @match_file_71:                ;Copy the file name
  913.     lodsb
  914.     stosb
  915.     or    al,al
  916.     jne    @match_file_71
  917.  
  918.     mov    al,SPACE        ;If file, add a space
  919.     test    byte ptr [bp-ffblk_attr],16 ;Subdirectory?
  920.     je    @match_file_72        ;No
  921.     mov    al,'\'            ;If subdir, add a backslash
  922. @match_file_72:
  923.     mov    byte ptr [di-1],al    ;Add a space or a '\'
  924.     mov    byte ptr [di],0
  925.  
  926. ;    Now hunt for more files. For each file found, keep the longest 
  927. ;    prefix in common so far.
  928.  
  929.     @GetNext            ;Get the next file name
  930.     jc    @match_file_80        ;No more files
  931.  
  932.     mov    di,[bp-fname]        ;DI->start of file name
  933.     lea    si,[bp-ffblk_name]    ;Name returned by GetNext
  934.     mov    cx,13            ;Max Length of field
  935.     repe    cmpsb            ;Compare strings
  936.     mov    byte ptr [di-1],0    ;Terminating null
  937.     jmp    short @match_file_72    ;Try for more files
  938.  
  939. @match_file_80:
  940. ;    Found one or more files, copy the longest common prefix
  941. ;    into the line buffer
  942.     mov    ax,[bp-lineptr]        ;AX->start of chars to be deleted
  943.     call    near ptr erase_to_dot    ;Delete characters between dot
  944. ;                     and start of name
  945.     lea    si,[bp-pname]        ;SI->name to be copied
  946.     mov    di,si
  947.     xor    al,al
  948.     mov    cx,64
  949.     repne    scasb            ;Hunt for terminating null
  950.     mov    ax,63
  951.     sub    ax,cx            ;AX<-length of string
  952. ; SI->string, AX is length
  953.     push    ax
  954.     call    near ptr xlate_lower    ;Convert to lowercase
  955.     pop    ax    
  956.     call    near ptr insert_at_dot    ;SI->source, AX == length
  957.  
  958. @match_file_90:
  959.     push    ds
  960.     mov    ds,[bp-oldDTAseg]
  961.     mov    dx,[bp-oldDTAoff]
  962.     @SetDTA    dx            ;Restore DTA
  963.     pop    ds
  964. @match_file_99:
  965. ; Restore previous state of break checking
  966.     mov    dl,byte ptr [bp-breakstate]
  967.     mov    ax,3301h
  968.     int    21h
  969.     mov    sp,bp
  970.     pop    bp
  971.     @restore
  972.     ret
  973. match_file endp
  974.  
  975.  
  976.  
  977. CSEG    ENDS
  978.  
  979.     END
  980.