📄 history.a86
字号:
; File : $HISTORY.A86$
;
; Description :
;
; Original Author : DIGITAL RESEARCH
;
; Last Edited By : $CALDERA$
;
;-----------------------------------------------------------------------;
; Copyright Work of Caldera, Inc. All Rights Reserved.
;
; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
; CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
; *** Current Edit History ***
; *** End of Current Edit History ***
;
; $Log$
; ENDLOG
;
; DOSPLUS Command Line Editor Routines
;
include pcmode.equ
include i:msdos.equ
include i:char.def
include i:cmdline.equ
PCM_HISTORY CSEG
public init_history, save_history
public del_history_buffers, del_cur_history_buffer
public prev_cmd, next_cmd, match_cmd, search_cmd
public prev_word, next_word, match_word
public goto_eol
public del_bol
public deln_word
extrn next_char:near
extrn save_line:near
extrn space_out:near
extrn bs_out:near
extrn goto_bol:near
extrn del_eol:near
extrn del_line:near
extrn char_info:near
extrn put_string:near
extrn prev_w20:near
extrn deln_w10:near
init_history:
;------------
; On Entry:
; SS:BP -> history structure
; On Exit:
; SS:SP filled in with appropriate history buffer
; Preserve DX
;
push ds
push es
push ss
pop es
lea di,RL_HIST_SEG ; point at history buffer variables
mov si,offset histbuf1 ; assume root buffer
test RL_FLAGS,RLF_INROOT ; root task after all?
jnz init_history10 ; if not we need to switch
mov si,offset histbuf2 ; application buffer
init_history10:
movsw ; copy the seg
lodsw ; get overall length
sub ax,2*WORD ; last two words contain pointers
stosw ; save the working length
xchg ax,si ; SI -> saved buffer positions
mov ds,RL_HIST_SEG ; in the buffer segment
movsw ; update save and
movsw ; recall positions
pop es
pop ds
ret
save_history:
;------------
; We are exiting from READLINE - if line has been modified save the
; current line and update our pointers.
;
test dx,dx ; skip update of sav/recall pointers
jz save_history30 ; if empty line
call save_current ; save away current command line
mov di,RL_HIST_SAVE ; start with the old one
call find_current_hist ; wrap it if we need to
call find_next_null ; find end of "new" command
inc di ; onto next character
cmp di,RL_HIST_SIZE ; do we need to wrap ?
jb save_history10
xor di,di ; wrap the line
save_history10:
mov RL_HIST_SAVE,di ; update "save" pointer
test RL_FLAGS,RLF_DIRTY ; if a line has been changed we'd
jz save_history30 ; better update "recall" pointer
mov RL_HIST_RECL,di ; too
save_history30:
push ds
push es
push ss ! pop ds
lea si,RL_HIST_SAVE ; point at history buffer variables
mov es,RL_HIST_SEG
mov di,RL_HIST_SIZE
movsw ; save the "save" pointer
movsw ; and the "recall" one
pop es
pop ds
ret
save_current_if_dirty:
;---------------------
test RL_FLAGS,RLF_DIRTY ; if data is dirty (ie. user modified)
jz save_current20 ; then save it
save_current:
;------------
; Copy current buffer contents to next free location in history buffer
;
push si
push di
push dx
cmp dx,RL_HIST_SIZE ; is history buffer big enough ?
jae save_current10 ; no, skip saving this line
call find_free_hist ; Find the next bit of space
pop cx ! push cx ; CX = chars to save
jcxz save_current10 ; none, forget about it
push ds
push es
lds si,RL_BUFPTR
mov es,RL_HIST_SEG
rep movsb ; and save the data.
xor ax,ax ; Null terminate it.
stosb
pop es
pop ds
push di
call find_next_null ; Find the end of the entry we just
mov cx,di ; overwrote - if any remains zap it
pop di
cld
xor ax,ax ; Null terminate this entry
sub cx,di ; Figure out number of zeros to write
jbe save_current10
push es
mov es,RL_HIST_SEG
rep stosb ; and pad to the next entry
pop es
save_current10:
pop dx
pop di
pop si
save_current20:
ret
;
; Here is the code to deal with history buffers
;
; match_cmd Does a string search based on what the user has typed so far
; search_cmd Matches string, but doesn't change match state
; prev_cmd Retrieves the previous command from the history buffer
; next_cmd " " next " " " " "
;
match_cmd:
mov al,@hist_flg ; is matching enabled ?
and ax,RLF_MATCH
jz search_cmd ; no, always match
xor RL_FLAGS,ax ; toggle match bit
test RL_FLAGS,ax ; turning matching off ?
jz match30 ; then just exit
search_cmd:
mov RL_SAVPOS,si ; any chars to save ?
test si,si
jz prev_cmd ; blank line - just get previous
call save_current_if_dirty ; save current line if it needs saving
push si ; save current offset in line
push di
push dx ; Save index to end of current line
mov dx,si ; discard rest of line if no match
mov di,RL_HIST_RECL ; Point to the current entry
match_loop:
call find_prev_hist ; DI-> previous cmd in buffer
push di ; save this command position
mov di,RL_HIST_RECL ; get starting position
call find_current_hist ; handle any wrapping
pop si ; recover previous command
cmp di,si ; have we been all round ?
je match_error ; YES - We've looped so no match found
push ds
push si ; save this entry
mov ds,RL_HIST_SEG
mov di,RL_BUFOFF ; ES:DI -> match string
mov cx,RL_SAVPOS ; try to match CX characters
repe cmpsb
pop di ; recover this entry
pop ds
jne match_loop ; try again if we didn't match
call copy_from_hist ; if it did match copy it
match_error:
pop cx ; Get end of displayed line
pop di ; user's buffer
pop si
push si ; save current position in lines
call space_out ; Rub the displayed line out
call bs_out ; And backspace to it's start
call goto_eol ; display the line
call goto_bol ; Move cursor to begining
pop cx ; CX = end of matched portion
mov RL_SAVPOS,cx ; CX = Current position in command
jcxz match20
match10: ; Move cursor forward to current
push cx ; position
call next_char ; next_char destroys our loop count
pop cx ; so keep it
loop match10
match20:
mov cx,RL_SAVMAX ; we can't copy any more
mov RL_SAVPOS,cx
match30:
ret
prev_cmd:
; Get the previous command from the buffer
test RL_FLAGS,RLF_RECALLED ; is this the 1st recall ?
jnz prev_cmd10
push cx
push di
mov di,RL_HIST_SAVE ; get existing "save" ptr
call find_current_hist ; wrap it if we need to
mov RL_HIST_RECL,di ; and update "recall" pointer
pop di
pop cx
prev_cmd10:
call save_current_if_dirty ; save current line if it needs saving
call del_line ; then delete it
push si
push di
mov di,RL_HIST_RECL ; point to the current entry
call find_prev_hist ; DI -> previous entry
jmps found_cmd ; now go and copy it to the user buffer
next_cmd:
; Get the next command from the buffer
call save_current_if_dirty ; save current line if it needs saving
call del_line ; then delete it
push si
push di
mov di,RL_HIST_RECL ; point to the current entry
call find_next_hist ; DI -> next entry
; jmps found_cmd ; now go and copy it to the user buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -