⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 history.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 2 页
字号:
;    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 + -