📄 editmgr2.asm
字号:
;* 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 + -