📄 uiedit.asm
字号:
ReEnd:
;Turn off highlighted text
cmp [fSelect],0ffffH
je short ReExit1
cCall MoveCursorPwndCur,<lnSelect, colSelect>
;See if another error has occurred while reporting this error
;For example, we ask user if he wants to edit an include file,
;user responds YES, and we load include file which causes error.
;
ReExit1:
cmp [uierr],0
je ReExit
jmp ReWhileErr
ReExit:
sub ax,ax
mov [b$ErrInfo],al ;reset extended error code
mov [ps.PS_bdErr.BD_cbLogical],ax ;release ASCII msg buffer
mov [fAdjustMsgBox],FALSE
and HelpFlags,NOT HLP_RTERR ; clear the flag
cEnd
;*********************************************************************
; void near ShowStmt(oRs, otx, col)
; Purpose:
; Makes a statement visible, activating list window if necessary.
;
; Entry:
; oRs - Text table containing the line to show
; otx - Offset in text table of line to display
; col - Column to position cursor on. If UNDEFINED,
; otx is used to compute column for start of stmt.
;
; Exit:
; alters contents of ps.bdpSrc
;
;*********************************************************************
cProc ShowStmt,<PUBLIC,NEAR>
parmW oRs
parmW otx
parmW col
cBegin
push [oRs]
cCall UiRsActivate
push [oRs] ;pass to ShowTok
push [otx] ;pass to OtxBosOfOtx
call OtxBosOfOtx ;ax = otx for beginning of stmt
push ax ;pass otx to ShowTok
push [col] ;pass col to ShowTok
call ShowTok
cEnd
cProc ShowTok,<PUBLIC,NEAR>,<si>
parmW oRs
parmW otx
parmW col
localW line
localW oldCol
cBegin
mov si, [oRs]
;If oRs is for a DECLARE or DEF FN prs, which has no text
;table, use the module's test table instead
cCall UiRsActivate,<si> ;grs.oRsCur = si
test [txdCur.TXD_flags],FTX_mrs
je NotMrs ;brif cur txt tbl is for procedure
mov si,[grs.GRS_oMrsCur] ;use module's oRs, so we don't
; activate oRs of DEF FN or DECLARE
cCall UiRsActivate,<si> ;grs.oRsCur = si
NotMrs:
cCall WndAssignList1 ;make grs.oRsCur visible in list window
; Which line is the statement on?
cCall LnOfOtx,<otx>
cmp [fLnNotIncl],0
jne SS_NotIncludedLine
; Line was in an include file.
; Turn on viewing of include files, and recalulate the line.
;
PUSHI ax,TRUE ; push TRUE
call CmdViewInclude
cCall UiRsActivate,<si> ; CmdViewInclude activates
; other text tables.
cCall LnOfOtx,<otx> ; ax = line
;Call cbGetLineBuf to set colStmtStart and colStmtEnd to mark the
;columns for the start and end of statement that surround grs.otxCONT
;
SS_NotIncludedLine:
mov [line],ax
cCall cbGetLineBuf,<si,ax,[ps.PS_bdpSrc.BDP_cbLogical],[ps.PS_bdpSrc.BDP_pb]>
mov dx,[col]
cmp dx,UNDEFINED
jne SS_SetCursor ; brif caller know's column
;We need to map otx to column, by listing the pcode.
mov ax,[otx]
mov [otxLsCursor],ax ; tell ListLine to find column
; offset for stmt
cCall OtxOfLn,<[line]> ; ax = otx for start of line
push ax ; pass otx to ListLine
PUSHI ax,<DATAOFFSET ps.PS_bdpSrc>
cCall ListLine ; ax = cbLine
; dx = column for otxLsCursor
inc ax ; test for UNDEFINED (out of memory)
jne NotOmErr1 ; brif not out-of-memory
; ax = 0 (just list a blank line)
call SetUiErrOm ; report error in msg loop
; dx is preserved
NotOmErr1:
inc dx ; test for UNDEFINED
je SS_SetCursor ; if UNDEFINED, column=0
dec dx ; restore dx=column equivalent to [otx]
;If showing current statement, force entire statement to be visible if possible
;by first positioning to end-of-stmt, then to start-of-stmt
;
SS_SetCursor:
mov [oldCol],dx ; save the column equivalent to [otx]
cmp dx,[colStmtStart] ; if we are at the start of a statement
jne SkipAddCursor ; then ensure entire statement visible
mov dx,[colStmtEnd]
SkipAddCursor:
cCall MoveCursorPwndCur,<[line],dx>
cCall MoveCursorPwndCur,<[line],[oldCol]> ; move back to old column
call DoDrawDebugScr ; update debug screen if a
or al,al ; new register set has been
; made active.
jne SS_Exit ; brif debug screen was redrawn
;If only change has been current line in active window, at least
; draw that window. We could have just called DrawDebugScr before
; DoDrawDebugScr and eliminated this code, but this is faster for
; animation.
cCall DrawWindow,<[pwndAct]>
SS_Exit:
cEnd
;**************************************************************************
; DoCmd(szCmd)
; Purpose:
; Setup to execute a direct mode command.
;
; Entry:
; szCmd points to a 0-byte terminated ASCII command to be executed.
; if szCmd == NULL, command has already been copied to ps.bdpSrc.
;
; Exit:
; If command contains no parser/scanner errors,
; fGotCmd == TRUE
; grs.bdlDirect contains pcode to be executed
; else
; uierr = error to be reported by GetCmd's loop
;
;**************************************************************************
cProc DoCmd,<PUBLIC,NEAR>
parmDP szCmd
cBegin
mov ax,[grs.GRS_oMrsMain]
inc ax ;test for UNDEFINED
jne DoCmdGotMain ;brif no main module
PUSHI ax,MSG_NoMainProg
call SetUiErr
jmp SHORT DoCmd_Exit
DoCmdGotMain:
;so edit mgr doesn't think it already has current line cached.
cCall EditMgrFlush1
mov cx,[szCmd]
jcxz DoCmd_EndOk
cCall SetPsBufSz,<cx>
DoCmd_EndOk:
mov [fDoCmd],sp ; sp is TRUE
mov [fGotCmd],sp
DoCmd_Exit:
cEnd
;**************************************************************************
; boolean NEAR CmdEnter()
; Purpose:
; Called by the main message pump to filter Carriage Return events
; out of the event stream when the command window is active. This
; allows CR to have a different meaning in the command window than it
; does in list windows. In a list window, it means split the line.
; In the command window, it means execute this entire line.
;
; Exit:
; If command window is active,
; Causes command to be executed
; If command contains no parser/scanner errors,
; fGotCmd == TRUE
; grs.bdlDirect contains pcode to be executed
; else
; uierr = error to be reported by GetCmd's loop
; returns TRUE
; else
; returns FALSE
;
;**************************************************************************
cProc CmdEnter,<PUBLIC,NEAR>,<si,di>
cBegin
mov bx,offset DGROUP:wndCmd ; bx -> command window's UWIN
cmp bx,[pwndAct]
je CE1 ;brif command window is active
; Ignore if command window is not active.
sub ax,ax ;tell caller it wasn't in Cmd Window
jmp CE_End
; Copy the line that ENTER was pressed on, and setup to execute it.
;
CE1:
mov cl,[bx.arcClipping.ayBottomArc]
sub cl,[bx.arcClipping.ayTopArc]; See if window has zero lines
jnz CmdEnterOk
jmp CE_ExitTrue ; return true
CmdEnterOk:
mov bx,[bx.pefExtra]
mov di,[bx.EF_ipCur_oln] ; Keep lnCmd in di
;flush dirty line in active window. Also makes sure edit mgr
; doesn't think it already has current line cached
call EditMgrFlush1
cCall cbGetLineBuf,<[hbufOfCmd],di,[ps.PS_bdpSrc.BDP_cbLogical],[ps.PS_bdpSrc.BDP_pb]>
sub ax,ax
cCall DoCmd,<ax>
mov si,[txdCur.TXD_cLines]
dec si ; si = number of last line (0..n)
js CE_BottomLine ; brif cmd window has 0 lines
cmp di,si
je CE_BottomLine ; brif editing bottom line
mov si,di ; si = command line
inc si ; si = line after command line
jmp SHORT CE5 ; (place to move cursor to)
; ENTER was pressed on the last line of the COMMAND window, so add a blank
; line to the end for the next command to be entered into.
;
CE_BottomLine:
sub ax,ax
inc si ; bump # lines in window
cCall InsertLineBuf,<[hbufOfCmd],si,ax,[ps.PS_bdpSrc.BDP_pb]>
je CE_ExitTrue ; brif line not inserted (out of memory)
; If there are more than ten lines in the command window then
; get rid of the first.
;
mov di,offset DGROUP:wndCmd ; di points to cmd wnd from now on
mov ax,si ; ax = #lines in window
sub ax,10d
jbe CE4 ; brif not more than 10
push ax ; pass oldest line to be deleted
cCall OtxOfLn ; ax = text offset to top line to delete
sub bx,bx
cCall TxtChange,<bx,ax,sp> ; delete top line of command window
mov bx,[di.pefExtra]
dec [bx.EF_pdCur_olnTop]
dec si ; decrement current line
; If there are more lines in the buffer than in the window, make sure that
; when the cursor is put on the last line (at CE5:), that that line is
; at the bottom of the window (so that the most possible history is displayed).
;
CE4:
sub ch,ch
mov cl,[di.arcClipping.ayBottomArc]
sub cl,[di.arcClipping.ayTopArc]
cmp cx,si
ja CE5
sub ax,ax
cCall MoveCursorPwndCur,<si,ax>
mov ax,si
sub ch,ch
mov cl,[di.arcClipping.ayBottomArc]
sub cl,[di.arcClipping.ayTopArc]
sub ax,cx
inc ax
sub bx,bx
cCall MoveCursorPwndCur,<ax,bx>
; Put the cursor on the last line of the buffer (the blank line we inserted).
CE5:
sub ax,ax
cCall MoveCursorPwndCur,<si,ax>
or si,si ;if the line is zero,
jz CE6 ;old line has disappeared
dec si
CE6:
mov [lnCmdLast],si ;save for error reporting
CE_ExitTrue:
mov ax,sp ;mov ax,TRUE
;ax = TRUE if Enter key was handled, FALSE if ignored (cmd window not active)
CE_End:
cEnd
;**************************************************************************
; fCodeWnd()
; Purpose:
; returns TRUE if the active window contains pcode.
;
; Entry:
;
; Exit:
; returns TRUE (nonzero in al/ax) if the active window contains code.
; condition codes set based on value in ax
;
;**************************************************************************
cProc fCodeWnd,<PUBLIC,NEAR>
cBegin
mov al,[mrsCur.MRS_flags2]
mov dx,FM2_NoPcode
and ax,dx ;isolate FM2_NoPcode bit
xor ax,dx ;ax = non-zero iff FM2_NoPcode 0
cEnd
;**************************************************************************
; GetSelText
; Purpose:
; Copies the selected text in the current window to the specified buffer.
;
; Entry:
; pb - Near pointer to where text is to go.
; cbMax - max number of chars to copy
;
; Exit:
; returns the number of chars copied.
; The string is copied to pb, and is null terminated.
;
;**************************************************************************
cProc GetSelText,<PUBLIC,NEAR>
parmW pb
parmW cbMax
cBegin
cCall GetEditText,<[pwndAct],[pb],[cbMax]>
cEnd
;***************************************************************************
; SetBookMark
; Purpose:
; Sets to the specified bookmark (0 to 3)
;
; Entry:
; cMark - integer in range 0 to 3 specifying bookmark
;
; Exit:
; Sets the specified bookmark to the current register set, otx, and column
;
;***************************************************************************
cProc SetBookMark,<PUBLIC,NEAR>,<si>
parmW cMark
cBegin
DbAssertRel cMark,b,MAXBOOKMARK,UI,<SetBookMark:cMark out of range>
mov si,dataOFFSET BookMarks
mov ax,size BookMark
mov cx,[cMark]
BookMarkValid:
mul cl
add si,ax
cCall GetEditLine
cmp pwndAct,OFFSET DGROUP:wndHelp ; displaying in help window
DJMP jne SetBookMarkNormal ; no, continue as normal
;Since pwndAct = &wndHelp, the help window must be open. Thus
;we must be displaying a topic, hense the buffers must be allocated.
DbAssertTst HelpFlags,nz,HLP_GOTBUF,UI,<SetBookMark:HLP_GOTBUF is FALSE>
push ax ; save edit line
cCall RetrieveHelpHistory ; pop last item
DbAssertRel cx,ne,0,UI,<SetBookMark:Help Open with no help history>
cCall RecordHelpHistory ; put it back
xchg ax,cx ; CX = low word of item
; DX = high word of item
pop ax ; AX = line #
jmp short SaveBookMarkVal
SetBookMarkNormal:
mov dx,NOT_HELPTOPIC ; flag as not a help topic
mov cx,[grs.GRS_oRsCur] ; Get oRs
SaveBookMarkVal:
mov [si].BM_Nc,dx ; save Nc
mov [si].BM_oRs,cx ; save oRs
mov [si].BM_oln,ax
cCall GetEditColumn
mov [si].BM_col,ax
SetBookMark_Exit:
cEnd
;***************************************************************************
; GotoBookMark
; Purpose:
; Moves to the specified bookmark (0 to 3)
;
; Entry:
; cMark - integer in range 0 to 3 specifying bookmark
;
; Exit:
; moves cursor to the specified bookmark
;
;***************************************************************************
cProc GotoBookMark,<PUBLIC,NEAR>,<si,di>
parmW cMark
cBegin
DbAssertRel cMark,b,MAXBOOKMARK,UI,<GotoBookMark:cMark out of range>
mov si,dataOFFSET BookMarks
mov ax,size BookMark
mov cx,[cMark]
mul cl
add si,ax
cmp [si].BM_oRs,UNDEFINED ; is this bookmark defined?
jne CheckHelpBookmark ; yes, go process it
Bleep_n_Exit:
cCall CowMoo ; inform user of problem
DJMP jmp short Nomark ; and exit
CheckHelpBookmark:
mov dx,[si].BM_Nc ; get high word of help id
cmp dx,NOT_HELPTOPIC ; reference a help topic?
je GotoBookMarkNormal ; no, process as normally
; we do not try to start the help system, as it is impossible
; to have a help book
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -