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

📄 editmgr2.asm

📁 dos 6.0 源代码 .对大家提高有一定的帮助。
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;*	SCCSWHAT( "@(#)editmgr2.asm	1.6 88/04/22 19:46:59	" ) */
;*
;*	COW : Character Oriented Windows
;*
;*	editmgr2.asm : Multi-line edit manager (part2)
;*	(included by editmgr.asm)

;*******************************************************************************
;_Del
;
;Purpose:
;	Delete the current ip character
;Entry:
;	ipCur
;	hBuffer
;	pdCur
;	ldCur
;Exit:
;	ldCur
;Uses:
;	si
;Exceptions:
;
;*******************************************************************************
cProc Del,<NEAR,PUBLIC>,<SI>
cBegin
ifdef	KANJI
	cCall	DbcsAdjCur
endif	; KANJI
	cCall	NoSelection			;remove any selected region
	cCall	ModifyLine			;mark line as modified
	jz	ExitDel
	mov	si, ipCur.ip_ob 		;check if ip after last char
	cmp	si, ldCur.ld_cb
	jb	NormalDel			;brif if ip < last char

	mov	ax, [clnCur]			;check if last line of file
	dec	ax				;last line is offset
	cmp	ax,ipCur.ip_oln
	jne	@F				;brif not last line

	cCall	NearBeep			;can't join line if last
	jmp	SHORT EndDel			;exit
;Here if a join line not del (i.e. del after last char)
@@:
	mov	ax,1				;reverse normal sense of join
						;which is above to below 
	cCall	JoinLine,<ax>			;current line
	jmp	SHORT EndDel			;exit

;Here if a normal del and not join
;si = ipCur.ip_ob
NormalDel:					;del works to right of ip
ifdef	KANJI
	mov	bx,[ldCur.LD_prgch]
	add	bx,si				;pointer to current line pos
	cCall	PchNextDbcs,<bx>		;Get next character
	sub	ax,[ldCur.LD_prgch]		; What is the new offset
	sub	ax,si				;delete 1 or 2 chars
	add	si,ax				;and move 1 or 2 for deleting
else	; KANJI
	mov	ax,1				;delete 1 char.
	inc	si				;so move 1 char for deleting
endif	; KANJI

	cCall	DelCh,<ax,si>
	cmp	si,pdCur.pd_obleft		;check if ip left of margin
	jge	@F				;brif if ip to right of margin
	cCall	DisplayCurPos			;recalc screen position
	jmp	SHORT EndDel			;exit

;Here if del did not move to left of left margin
@@:
	cCall	RefreshLine,<ipCur.ip_oln>	;refresh current line
EndDel:
	mov	[fResetAnchor], 1
ExitDel:
cEnd

;*******************************************************************************
;EMGetWord
;
;Purpose:
; Copies the word the cursor is on (or just after) to fpWord
; The string is null terminated.
; no more than cbMax bytes (including null) will be copied.
;
;Entry:
; fpWord - Where to store the word.
; cbMax  - Max number of chars to copy.
;
;Exit:
; Return number of bytes in the current word.
;
;Uses:
;Exceptions:
;
;*******************************************************************************

cProc EMGetWord,<NEAR,PUBLIC>,<SI,DI>
	parmD	fpWord
	parmW	cbMax

	localW	cb
cBegin

; Leave room for the null terminator
	dec	[cbMax]

	xor	ax,ax
	mov	[cb], ax

	cCall	GetLineScratch,<[ipCur.ip_oln]>
	mov	di, [ipCur.ip_ob]
	mov	ax, [ldEMScratch.ld_cb]
	cmp	di, ax
	jb	GW1
	dec	ax
	mov	di, ax
GW1:
	mov	si, [ldEMScratch.ld_prgch]
	add	si, di

GW2:
	inc	di
	jz	GW5
	dec	di


	cCall	IsWordChar,<[si]>
	or	ax,ax
	jnz	GW3

	dec	si
	dec	di
	jmp	short GW2

GW3:
	inc	di
	jz	GW5
	dec	di

	cCall	IsWordChar,<[si]>
	or	ax,ax
	jz	GW5

	dec	si
	dec	di
	jmp	short GW3
GW5:
	inc	si

	mov	dx, di
	les	di, fpWord

GW6:
	cmp	dx, [ldEMScratch.ld_cb]
	jae	GW7
	mov	ax, [cb]
	cmp	ax, [cbMax]
	jae	GW7
	push	dx
	cCall	IsWordChar,<[si]>
	pop	dx
	or	ax, ax
	jz	GW7

	lodsb
	stosb
	inc	[cb]
	inc	dx
	jmp	short GW6

GW7:
	xor	al,al
	stosb
	mov	ax, [cb]
cEnd

cProc NearBeep,<NEAR,PUBLIC>
cBegin
;;;	cCall	Beep
	xor	ax,ax
	cCall	DoSound,<ax>
cEnd

cProc SetInverseIsa,<FAR,PUBLIC>
	parmW	isa

	localW	coBack
	localW	coFore
cBegin
	;set up the isa isaUserMax-1 to be the inverse of the
	;specified isa.
	push	isa
	lea	ax, coBack
	push	ax
	lea	ax, coFore
	push	ax
	cCall	GetIsaColor
	mov	ax, isaUserMax-1
	push	ax			;*	isa
	push	coFore
	push	coBack
	mov	ax,coFore
	cCall	SetIsaColor

	mov	ax, isaUserMax-1	;return value
cEnd


;/***
;	TabOrBackTab - Handles single or multi line Tab or BackTab.
;	Description:
;		Do Tab/BackTab over all the selected lines (or just the current
;		line if no selection).
;	Input: DX - TRUE for BackTab
;	Output:
;****/
cProc TabOrBackTab,<NEAR,PUBLIC>,<SI,DI>

	localW	fBack
	localD	ipSave
	localB	fInsertModeSave
	localW	olnFirst
	localW	olnLast
	localW	obFirst
	localW	obLast
cBegin
	mov	[fBack], dx
	mov	al, 1
	xchg	al, [fInsertMode]
	mov	[fInsertModeSave],al

	mov	ax, [ipCur.ip_oln]
	mov	word ptr [ipSave.ip_oln],ax
	mov	ax, [ipCur.ip_ob]
	mov	word ptr [ipSave.ip_ob],ax

	lea	ax, olnFirst
	lea	bx, obFirst
	lea	cx, olnLast
	lea	dx, obLast
	cCall	BuildSelection,<ax,bx,cx,dx>
	cCall	GetCurLine

	mov	si, User_EditOFFSET Tab
	cmp	[fBack], 0
	jz	TBT_1

;
; We are BackTabing, figure out how much to backtab.
;
	mov	si, User_EditOFFSET BackTab

	mov	ax, [olnFirst]
	cmp	ax, [ipCur.ip_oln]
	je	TBT_1a
	cCall	GetLine,<ax>
TBT_1a:
	cCall	obGetFirst
	mov	di, ax
	or	ax,ax
	jz	TBT_1
	cCall	obGetPrev
	sub	di,ax

TBT_1:
	mov	ax, [olnFirst]
	cmp	ax, [olnLast]
	jne	TBT_MultiLineSelection

;
; No selection Tab or BackTab is simple
;
	cCall	NoSelection
	call	si
	jmp	TBT_Common

TBT_MultiLineSelection:
;
; For multiline selection, we want to Tab or BackTab each line
;

	cmp	[obLast], 0
	jne	TBT_3
	dec	[olnLast]
TBT_3:
	cCall	UpdateLine
	mov	ax, [olnFirst]
	mov	[ipCur.ip_oln], ax
	or	[emState], ES_NOREDRAW

TBT_NextLine:
	mov	[ipCur.ip_ob],0
	call	si
	inc	[ipCur.ip_oln]
	mov	ax, [olnLast]
	cmp	ax, [ipCur.ip_oln]
	jae	TBT_NextLine

	and	[emState], NOT ES_NOREDRAW
	mov	ax, word ptr [ipSave.ip_oln]
	mov	[ipCur.ip_oln], ax
	mov	ax, word ptr [ipSave.ip_ob]
	mov	[ipCur.ip_ob], ax
	mov	[fResetAnchor], 0

TBT_Common:
	mov	ax, [pdCur.pd_obleft]
	add	ax, [cColumnsCur]
	cmp	ax, [ipCur.ip_ob]
	ja	TBT_4
	cCall	DisplayCurPos
	jmp	short TBT_5

TBT_4:
	cCall	RefreshLines,<[olnFirst],[olnLast]>
	

TBT_5:
	mov	al, [fInsertModeSave]
	mov	[fInsertMode], al
cEnd

;*******************************************************************************
;_Backspace 
;
;Purpose:
;	Do a destructive backspace
;Entry:
;	ipCur
;	ldCur
;Exit:
;	ldCur
;Uses:
;	si - cbDel
;	di - obFirstCur
;	obFirstPref
;Exceptions:
;
;*******************************************************************************
cProc Backspace,<NEAR,PUBLIC>,<SI,DI>
cBegin
ifdef	KANJI
	cCall	DbcsAdjCur
endif	; KANJI
	cCall	NoSelection			;Turn off any selection
	cCall	ModifyLine
	jz	ExitBackspace
	cmp	ipCur.ip_ob,0			;If at start of line do join
	jne	BackspaceNormal 		;brif not at start of line

;Here if backspace at start of line. Then we join with line above
	cmp	ipCur.IP_oln,0
	jne	JoinOk
ifndef SILENT
	cCall	NearBeep
endif
	jmp	SHORT ExitBackspace			;exit

JoinOk:
	sub	ax,ax			;set false to join below
	cCall	JoinLine,<ax>
	jmp	SHORT ExitBackspace			;exit

;Here if backspace is not at start of line
BackspaceNormal:
	mov	ax,[ldCur.LD_cb]
	or	ax,ax
	mov	ax,[ipCur.IP_ob]
	jz	@F
	cCall	obGetFirst			;get beginning text on line
@@:
	mov	di,ax
ifdef	KANJI
	mov	ax,[ldCur.LD_prgch]
	mov	si,[ipCur.ip_ob]
	add	si,ax
	cCall	PchPrevDbcs,<si,ax>
	or	ax,ax				;If NULL, we are off end
	jz	@F
	sub	si,ax
	jmp	SHORT CheckBackspaceIndent
@@:
	mov	si,1				;default deletions = 1
CheckBackspaceIndent:
else	; KANJI
	mov	si,1				
endif	; KANJI

	cmp	ipCur.ip_ob,di			;check to adjust indent
	jne	@F				;if at start of line or blank

;Here if at start of indent on line
	cCall	obGetPrev		;get new indent. level
	mov	si,di
	sub	si,ax			; si = delta to move line left

;Here when ready to delete either 1 or n characters
@@:
	cCall	DelCh,<si,[ipCur.ip_ob]>
	sub	ipCur.ip_ob,si		;adjust ip for deletion
	cCall	DisplayCurPos		;recalc screen position
	cCall	RefreshLine,<[ipCur.ip_oln]>
ExitBackspace:
	mov	[fResetAnchor], 1
cEnd

;*******************************************************************************
;_Tab
;
;Purpose:
;	Insert a tab at current ip. Adjust screen
;Entry:
;	ipCur
;	pdCur.obleft
;Exit:
;	ldCur
;	ipCur
;Uses:
;	si - obCur
;Exceptions:
;
;*******************************************************************************
cProc Tab,<NEAR,PUBLIC>,<SI>
cBegin
	cCall	GetCurLine
	cCall	NextTab,<[ipCur.ip_ob]>
	mov	si, ax			;offset for next tab position
	mov	ax,ldCur.ld_cbMax	;Make sure tab is within line
	dec	ax
	cmp	si, ax			;check if next pos. with line
	jnb	$I511			;brif if tab was within line
	mov	cx, [ldCur.ld_cb]
	jcxz	Tab_JustMove
	jmp	short $I511a

$I511:
	cCall	NearBeep		;warn user
	jmp	SHORT ExitTab

;Here if tab is within max line width and not on a blank line.
$I511a:
	cCall	ModifyLine
	jz	ExitTab
	mov	bx,32
	mov	ax, si			;calc. # of spaces to add
	sub	ax,ipCur.ip_ob
	mov	cl, [fInsertMode]
	cCall	InsCh,<ax,bx,cx>	;insert tabs for spaces
Tab_JustMove:
	mov	ipCur.ip_ob,si		;update current pos. after tabs
ExitTab:
cEnd

;*******************************************************************************
;_InsCh
;
;Purpose:
;	Low level routine to insert a character into ldCur at ip
;Entry:
;	cbAdd
;	InsertCh
;	ipCur
;	ldCur
;Exit:
;	ldCur
;Uses:
;	ob - offset to start insertion
;	cbFill - # of space to insert before char. (if ip of end of line)
;	cbMove - # of character to move to right of ip
;	pIns - buffer pointer to start move
;	di - ldCur.cb
;	si - cbAdd
;Exceptions:
;
;*******************************************************************************
cProc InsCh,<PUBLIC,NEAR>,<SI,DI>
	parmW	cbAdd
	parmB	char
	parmB	fInsert

	localW	pIns
cBegin
ifdef	KANJI
	sub	ah,ah
	mov	al,[fCharIsDbcs]		; See if we have
	dec	ax				;   a DBCS byte
	jns	@F				; If not
	cCall	DbcsAdjCur			;   then Adjust cursor
	jmp	SHORT StartInsCh

@@:						; otherwise
	dec	ax				;   See if we have second byte
	js	StartInsCh			;   If we do
	mov	[fCharIsDbcs],al		;     Then clear flag
StartInsCh:
endif	; KANJI

; registers SI = cbAdd
;           DI = ldCur.cb
;
	mov     si,[cbAdd]
	mov     di,[ldCur.LD_cb]

;
; Are we past the current end of the line?
;
	mov     ax, [ipCur.IP_ob]
	cmp     [ipCur.IP_ob],di
	jle	@F

;
; Fill from end of line to cursor with spaces
;
	sub     ax,di				; cbFill = ipCur.ob - ldCur.cb;

	push    ax
	mov     ax,' '
	push    ax
	mov     ax,[ldCur.LD_prgch]
	add     ax,di
	push    ax
	call    _memset
	add     sp,6

	mov     di,[ipCur.IP_ob]		; ldCur.cb = ipCur.ob;

;
; If cbAdd is too big, figure out how much can be added
;
@@:
	mov     ax,[ldCur.LD_cbMax]
	dec	ax
	cmp     [fInsert],0
	je	@F

	sub     ax,di			; cbMax = ldCur.cbMax - 1 - ldCur.cb
	jmp	short $LL20042

@@:
	sub     ax,[ipCur.IP_ob]	; cbMax = (ldCur.cbMax - 1) - ipCur.ob

$LL20042:
	cmp     ax,si			; Is cbMax >= cbAdd
	jae	@F			; Yes
	mov	si, ax			; cbAdd = cbMax

;
; Now, if there is any room, do it
@@:
	or      si,si
	jle	EndInsCh

	mov     ax,[ipCur.IP_ob]
	add     ax,[ldCur.LD_prgch]
	mov     [pIns],ax

	cmp     [fInsert],0
	je	OverwriteInsCh

;
; We are in Insert Mode so move the stuff after the cursor to make room for
; the stuff we are inserting.
;
	cmp     [ipCur.IP_ob],di
	jge	@F

	mov     ax,di
	sub     ax,[ipCur.IP_ob]

	or      ax,ax
	je	@F

ifdef	PROJECT_QB
	mov     bx,[pIns]
	push	bx				; source
	add     bx,si
	push    bx				; dest
	push	ax				; count
	call	bltbyte			 	; pascal Calling convention
else	;PROJECT_QB
	push    ax
	push    [pIns]
	mov     ax,[pIns]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -