home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
sprint
/
texmac.zip
/
NOTHER.SPM
< prev
next >
Wrap
Text File
|
1991-11-26
|
62KB
|
2,189 lines
; NOTHER.UIM -- SP.SPM replacement
; Last Update: 1/6/91, RDT
; CONTENTS:
;; SECTION: Routines whose definitions are to be removed.
; SECTION: General and command macros sub-grouped by function
; subsection: miscellaneous semi primitives
; subsection: object/unit movements, jumps
; subsection: text manipulation, word wrap, newlines, etc
; subsection: columns
; subsection: regions, selection, deletions
; subsection: locate, search & replace
; subsection: macro management
; subsection: file management
; subsection: window management
; subsection: direction / unit control
;
; SECTION: Automatically-called macro definitions (Main, Init,
; EditKey, MenuKey, etc.)
;----------------------------------------------
;; SECTION: Forward declarations -- Things I don't use but
; have kept in the macros for easier modification by others
; These have no space before : to distinguish from real defs.
;----------------------------------------------
;Restart: ; needed for prmenu.uim but defined in Auto. macros later.
DefaultRuler: ; just cause sometime someone might want it again
CheckLastWord:
NeedDisk: ; see UnloadEngine
SetQDDiskName: ; get it from core.spm if you have floppy system
regionupper:
regionlower: ; see region section
;----------------------------------------------
; SECTION: General and command macros sub grouped by function
;----------------------------------------------
; subsection: miscellaneous semi primitives
; --- Replacements for old unnumbered mark commands:
aftermark : after themark
beforemark : before themark
setmark : set themark
swapmark : if (inbuff themark) swap themark
tomark : to prevmark
togmark : to gmark
Unselect : 0->select
MarkSelect : setmark 1->select
IsNotSelect : (!select || (select && !inbuff themark))
; True if nothing is selected or selection is in another buffer
IsSelect : (select && inbuff themark) ; could use to protect against
; Can't copy, mark not in buffer error.
MaybeSelect : if !select (setmark 1->select) 0->ColMode ; force columns off
BlockCursor : ; my preference
hardware "0fh int 10h" & 0ffh =7 ? {hardware "14>cx 1 int 10h"} : {hardware "8>cx 1 int 10h"}
; Normal keystroke input, converts IBM function keys into 256+'scan code':
;KeyGet : key || key + 256
KeyGet :
int ktmp
key || key + 256
->ktmp
if ((ktmp > 1afh)&&(ktmp <1bah)) (ktmp - 180h)
else ktmp
GetKey: KeyGet ; old name
Arg : ; QD = prompt
->n
message "\n"
message QD
n status ": %d"
key->x
if (x >= '0' && x <= '9') {
x - '0'->n
do {
message "\n"
message QD
n status ": %d"
key->x
if (x >= '0' && x <= '9') (n * 10 + x - '0'->n)
else break
}
}
x keypushback
n
AtPara : ; Return TRUE if point is at a real paragraph to be filled
mark (ispara && ((f c ispara) || iswhite || isend || (current = '^L') || (current = '^K')))
IsAlpha : (
current >= 'a' && current <= 'z') || (current >= 'A' && current <= 'Z')
IsBlankLine : ispara && column = 0
IsLower : current >= 'a' && current <= 'z'
IsOnlyRuler : (length ==0) || (mark (r to isend inruler && (toeol c isend)))
IsParaEnd : ; check for end of paragraph (after a NL)
isgray || (3 match "[@./\\\\)}\\]]") ; added tex esc. char \\\\
IsShift : 0->peekseg isibm && (peek 417H) & 3
IsSol : mark (!(r c) || isnl)
IsUnnamed : length fname = 0
IsUpper : current >= 'A' && current <= 'Z'
Null : ; do nothing macro
NoBlock : error "You must mark a block first."
ToLower : if IsUpper (current + 20H->current) else c
ToUpper : if IsLower (current - 20H->current) else c
RateChange :
if !keypressed 0
else {
KeyGet - 30h->x ; convert numbers '0'-'9' to 0-9
if (x < 0 || x > 9) 1
else {
if x (x * 50 ->RepeatRate) ; 0 is super fast, other in 50mS increments
else 1->RepeatRate
0
}
}
CharToAlpha :
; why bother when there's x,y,n ?
if (x >= 188h && x <= 193h) (x - 180h -> x)
if (x >= 'a' && x <= 'x') (x - 32->x)
if (x >= '^A' && x <= '^X') (x + 64->x)
x
CharToUpper : int z
z >= 'a' && z <= 'z' ? z - 20h : z
Quote :
(if !inagain {
if (!menudelay || !(menudelay wait)) {
status "\nControl character to insert: "
}
KeyGet & 9fh ->Quoted
}
$)
if inruler (toeol c)
repeat {
Quoted case {
32 '^\' insert,
'-' '^^' insert,
'^[' if ask "Insert [ESC] character? " ('^[' insert),
'^K' '^K' insert readruler,
188h '^H' insert,
189h '^I' insert,
18ah '^J' insert,
18dh '^M' insert,
$ Quoted insert
}
}
QuoteHack : ; This is a hook called by all the search-type
; functions so that you can hack escape/wild card/
; quote characters
CountRepeat :
set QD "Repeat" 1 Arg->RepCount
key -> RepChar
if (RepChar >= 32) {
RepCount repeat (RepChar keypushback dokey)
}
else {
RepChar keypushback
RepCount dokey
}
KeyRepeat :
if !InRepChar {
++InRepChar
status "\nKey to repeat: "
KeyGet->RepChar
stopped while !RateChange {
RepChar keyexec
message "\nRepeating key. Press 0-9 to adjust rate, any other key to stop"
draw RepeatRate wait
}
}
else error "You can't repeat repeat."
0 ->InRepChar
status ""
RightEdge : ; returns rightmost column number
mark (toeol column)
Showpos : offset message "point=%u " length message "of %d"
TimeMonth : ; Insert the month
time 4 - 1 put "%[January%;February%;March%;April%;May%;June%;July%;August%;September%;October%;November%;December%]"
TimeWeekDay : ; Insert the day of week
time 6 put "%[Sunday%;Monday%;Tuesday%;Wednesday%;Thursday%;Friday%;Saturday%]"
TimeDateLong : ; Insert the date as 'January 1, 1988'
TimeMonth
time 3 put " %d, "
time 5 + 1900 put "%d"
TimeDateShort : ; Insert the date as '1/1/88'
time 4 put "%d/"
time 3 put "%d/"
time 5 put "%d"
TimeDayDate :
TimeWeekDay insert ", " TimeDateLong
TimeTime : ; Insert time as HR:MIN:SEC AM/PM
0->x ; AM/PM flag
time 2->y ; hours
if (y > 11) (1->x y - 12->y)
if !y (12->y)
y put "%d:"
time 1 put "%02d:"
time 0 put "%02d"
x put " %[am%;pm%]"
ToggleIns : ++overwrite
Zap : Unselect 1 Bell abort
;----------------------------------------------
; subsection: unit (object) movements, jumps
CharFind : ; case insensitive move to char, maps ^M to NL.
; returns 1 if found, 2 if illegal key, else false
key->x
if (x < ' ') {
x case {
'^M' '^J' ->x, ; map return to NL
'^I',
'^J',
'^L',
$ if !x keypushback 2 return ; function keys are returned
}
}
x CharToUpper ->x
direction ? { ; Forward Search
if ((x < 'A') || ((x > 'Z') && (x < 'a')))
(x csearch) ; literal search for non-alpha chars
else {
to (current = x) || (current = (x + 20h))
}
}
: { ; Reverse Search
if (x < ' ') (x r csearch) ; literal search for control chars
else {
r to (current = x) || (current = (x + 20h))
}
}
CharFindBack :
status "\nFind <- "
mark {
r CharFind case {
1 r c setmark,
2 return,
$ message "\nNot found"
}
}
CharFindFwd :
status "\nFind -> "
mark {
CharFind case {
1 setmark,
2 return,
$ message "\nNot found"
}
}
Up : (if action (tosol setmark) $)
repeat (tosol r c)
if action tosol
else (dcolumn->dcolumn)
$
Down : (if action (tosol setmark) $)
repeat (toeol c)
if !action (dcolumn->dcolumn)
$
FileEnd : if !(IsSelect || isend || r isend) setmark
f toend
FileStart : (if !(IsSelect || isend || r isend) setmark $)->line
LineJump : if !IsSelect setmark
LastLine get "Line number" -> LastLine -> line
if (line < LastLine) message "\nLine was out of range. At end of file"
if (LastLine < line) { 1->LastLine message "\nAt beginning of file"}
LineFwd : repeat (past isnl to isnl) ; end of line, down
;(RightEdge > column) ? toeol : Down toeol)
LineBack : repeat r (past isnl to isnl) ; start of line, up
; column = 0 ? Up : tosol)
LineNext : repeat (to isnl past isnl) ; start of line, down
LinePrevious : r LineNext ; end of line, up
Left : repeat r c
MarkerBack : ;apologies to hch, goes to previous mark in jump ring
; while (!inbuff marknumber NextMnum) (NextMnum+9)%10->NextMnum ; stay in current buffer
if !IsSelect setmark
to marknumber NextMnum
NextMnum message "Back to Mark %x"
(NextMnum+9)%10->NextMnum
; it seems more functional & intuitive to decrement nextmnum AFTER
; cuz I probably want to go to the mark I just set.
MarkerFwd : ;rdt goes to next mark in jump ring
; while !(inbuff marknumber NextMnum) (NextMnum+1)%10->NextMnum
(NextMnum+1)%10->NextMnum
if !IsSelect setmark
to marknumber NextMnum
NextMnum message "Forward to Mark %x"
MarkerMark : ;apologies to hch sets a mark and puts it in mark stack
++Mnum%10->Mnum
set marknumber Mnum
Mnum message "Mark %x set"
Mnum->NextMnum ;sets mark in jump ring
MarkerJump :
status "\nGo to marker (0-9): "
KeyGet - 30h -> x
(x< 10 && x >= 0)? {
x ismarkset ? (if !IsSelect setmark to marknumber x)
else message "\nMarker not set." } else abort
; goes to previous position in file if no marker entered
MarkerSet :
status "\nSet marker (0-9): "
KeyGet - 30h -> x
(x < 10 && x >= 0)? (set marknumber x message "\nMarker set") else abort
ParagraphBack : repeat {if !WordWrap {
; r past isgray r to ispara f past isgray
r past isgray r to IsBlankLine
}
else { r past isgray
while ('^J' r csearch) {
c
if (IsParaEnd) break ;
r c
}
past isnl ; stays at sol
}
}
ParagraphFwd : repeat {if !WordWrap {
; past isgray action ? setmark ; ??
; to ispara past isgray ;clings to text
past isgray to IsBlankLine past isgray
}
else { past isgray
while ('^J' csearch) {
c
if (IsParaEnd) break
}
past isnl ; get's to start of next
}
}
Right : repeat c
ScreenBack :
|| wlines-scrollborder -> x if x<=0 (1->x)
x repeat (tosol r c)
if r isend return
x r scroll
dcolumn->dcolumn
ScreenFwd :
|| wlines-scrollborder -> x if x<=0 (1->x)
x repeat (toeol c)
if isend return
x scroll
dcolumn->dcolumn
SentenceBack :
repeat {
; if !WordWrap { 3 r search "[{(\[<]" r c ; \" }
; else { ; look for programming fences
r to istoken
do {
r to (issent || current = ';')
r c
if (current != '^J') {
c
past isgray
break
}
}
; }
if inruler (toeol c)
}
SentenceFwd :
repeat {
; if !WordWrap ( 3 search "[}\\])>]" c ;\" )
; else { ; look for programming fences
do {
past isgray
to (issent || current = ';') ; include semicolons in sentence punc. set.
if (current = '^J') c
else {
to isgray
break
}
}
; }
}
WordBack : repeat (r to istoken r past istoken)
WordFwd : repeat (to istoken past istoken)
WordSelect :
repeat (WordFwd WordBack MaybeSelect repeat WordFwd)
;======================= HOME ========================
; Date: 7 April 90
; Author: Herman Kuun (70741,1044)
; Keyboard Function
;------------------
;
; HOME => To start of line
; HOME HOME => To start of file
;
newHOME : SentenceBack ; put into ^Home 167h
draw
; if (300 wait) { ; 400 is too slow
; if (KeyGet = 147h) (ScreenTop)
; draw
; HOME HOME => To top of screen
if (250 wait) {
if (KeyGet = 167h) (FileStart)
draw
}
; }
newEND : SentenceFwd
draw
; if (300 wait ) { ; 400 is too slow
; if (KeyGet = 14fh) (ScreenBottom)
; draw
if (250 wait) {
if (KeyGet = 16fh) (FileEnd)
draw
}
; }
;----------------------------------------------
; subsection: text manipulation, word wrap, newlines, etc
EraseWhite : erase past iswhite r erase past iswhite
CaseChange :
mark {
if !istoken (r to istoken past istoken)
if IsLower ToUpper ; uppercase first letter
else if (c && istoken && IsLower)
(r c while (istoken) ToUpper) ; to uppercase
else (r c while (istoken) ToLower) ; to lowercase
}
FWCaseRotate :
mark {
to isvisible
if !istoken WordBack
CaseChange
}
CaseRotate : ; rotate case To->TO->to->To...
mark {
int type
if !select WordSelect else if beforemark swapmark
regionfwd {
mark {
past istoken r (to IsAlpha c) ; check what end of word is
IsLower ->type ; save case in type
}
if (type && IsLower) (ToUpper r c) ; word all lc so just set initial cap
else if (type && IsUpper) RegionUpper ; convert to all UC
else RegionLower
}
Unselect
}
CaseSwitch :
if select
(regionfwd IsUpper ? RegionLower : RegionUpper Unselect)
else NoBlock
CaseInitCap : ; macro to convert a region such as a heading to initial caps
; For use in macros, where you want consistent results
; if !select {tosol setmark toeol} ; define current line
RegionLower ; init to lowercase
markregion { ; get to start
while beforemark {
ToUpper
to isgray to istoken
}
}
Unselect
CaseInit : ; macro to cycle through a region's initial capitalization
; this will be an INTERACTIVE macro since results vary depending on current capitalization
markregion (
while beforemark {
(CaseChange $)
to isgray past isgray
} ; single letters A are problem cause they change more often that multi letter words
) ; leave it in select for cycling
TabIndent :
->x $
r erase past iswhite
if (column < x) {
while (column < x) ('^I' insert)
if (column > x) {
r del
x - column repeat (insert " ")
}
}
TabIndent : ; x is tab stop to go to. column nexttab produces next column # to go to
->x $ ; adjusted to use spaces, not ^I
r erase past iswhite ; remove all previous whitespace
if (column < x) {
while (column < x) (' ' insert)
}
; substitute this for tabindent if you want spaces instead of tab characters
; see regiontab and detab in column to convert to spaces
TabAction :
do {
insert " "
}
while ( (column+1) % tabsize )
TabBack : ; remove tabs and spaces around cursor
EraseWhite
; column->x 1 r erase past iswhite
; while (x>column && !(x nexttab < dcolumn)) --x
; x>column ? (x nexttab TabIndent)
ALineFill : ; returns true if line was filled.
0-> int filled
if (!rightmargin && ALineLength && column > ALineLength) {
mark {
while (r past iswhite column > ALineLength) (r to isgray)
if (column && (past iswhite beforemark))
(r c '^J'->current ++filled)
if AutoIndent { ; if indent is on, do it.
r c tosol
past iswhite
column (isnl ? erase tosol toeol c $) TabIndent
}
}
}
filled
; This reformats in ascii wrap mode, and fixes corrupted screens.
Reformat :
0 redraw draw ; So the command also fixes corrupt screens...
mark {
if (ALineLength && !rightmargin) {
status "\nFilling..." ; filling ASCII text, no rulers
r to AtPara ; go to top of current paragraph
c
do {
toeol
if !AtPara {
32->current ; replace NL's with spaces
}
} while !AtPara
ALineLength->column ; go to first wrap position
while (column = ALineLength && !AtPara) {
if !iswhite (r (to (iswhite || AtPara) c))
'^J'->current
ALineLength->column ; next wrap position
}
}
else message "\nScreen refreshed." ; for files w/rulers
}
QuickFill : ; skips preceding part of paragraph to save time.
; calling routine must decide to call this based on WordWrap flag
mark { if (ALineLength && !rightmargin) {
do {
toeol
if !AtPara {
32->current ; replace NL's with spaces
}
} while !AtPara
ALineLength->column ; go to first wrap position
while (column = ALineLength && !AtPara) {
if !iswhite (r (to (iswhite || AtPara) c)) ; screws up if no wordspaces in line, ie row of -------
'^J'->current
ALineLength->column ; next wrap position
}
} ; end alinelength test, if not, do nothing to current paragraph
}
redraw
EditFill : QuickFill
; point of this is only to have easy way to control when qfill happens
EditFill: ; I want this to do nothing now
FileFill : ; reformat all paragraphs in file
if !AlineLength message "\nNo line length set"
else (
status "\Filling file"
r toend
while !isend {Reformat ParagraphFwd}
)
RegionFill : ; reformat all paragraphs in region
if IsSelect {
status "\Filling region"
markregion (
while beforemark {Reformat ParagraphFwd}
)
Unselect}
else Reformat ; just do the paragraph
BreakTest : ; decides whether to wrap at screen edge plus puncbreak
if (column > ALineLength) (ALineFill $) ; if at line end, move to next
else if (RightEdge > ALineLength) ; but if in line
(EraseWhite "^J" left) ; do LineOpen
ASpace : if (overwrite && current != '^J') del
insert " " ; actually inserts space char
SpaceInsert :
(if AutoCorrect CheckLastWord $)
WordWrap case {
0 ASpace, ; do on wrapping
1 QuickFill ; normal type of word wrap
ASpace,
2 previous case { '.', '?', '!', ';', ':' "^J", ; break after punc. mark
$ BreakTest ASpace} ; or does it need wrapping + space char?
}
TabInsert : ; fwii.spm
if AutoCorrect CheckLastWord
column nexttab
TabIndent
if WordWrap = 1 QuickFill
NewLineInsert :
'^J' insert
; if (!WordWrap) ('^J' insert) ; : (' ' insert)
NewLineIndent : NewLineInsert r c tosol past iswhite column
(isnl ? erase tosol toeol c $)
TabIndent
NewLinePressed : (if AutoCorrect CheckLastWord $)
AutoIndent ? NewLineIndent : NewLineInsert
LineOpen : repeat ('^J' insert r c)
;LineOpen : (NewLineInsert $) r c
LineIndent : mark (tosol TabInsert) ;sp.spm
CharTranspose : r c r c current (1 del c $) insert
;LineTranspose : mark(tosol delete (toeol c) QD toeol c insert QD)
LineTranspose :
tosol
if (r isend) Down
delete (f toeol c) QD
Up tosol
insert QD
WordTranspose : ; to preserve kill buffer, this uses QC, though it shouldn't
if (f isend) WordBack
if (r isend) WordFwd
f to istoken
delete (past istoken) QD
delete (r to istoken) QC
r past istoken
insert QD
insert QC
set QC ""
CharFindDelete :
status "\nDelete to: "
mark {
if (CharFind = 1) (delete tomark 1->AppendNext set markF) ; use top of mark list first
}
WordBackDelete :
r delete (repeat WordBack) 1->AppendNext set markF
EditFill
DelFwd : del EditFill
DelBack : if overwrite r c else r del
EditFill
;----------------------------------------------
; subsection: columns
; maybe otta just fwd declare stuff.
;#include "column"
Coltab:
ColDeTab:
ColCopy:
ColDelete:
ColInsert:
ColErase:
ColSetOneEnd:
;----------------------------------------------
; subsection: regions, selection, deletion
FileSelect : r toend MarkSelect toend
UndeleteN : ; changed so I can reselect an inserted block, this leaves the mark BEFORE the insertion point.
if (r !isend) { ; if not at start of file, clumsy fix
r c setmark f c ; adjust point for bad mark placement, so it doesn't get "pushed down" by the insertion
} else setmark $ ; so it won't save mark correctly at start of file
repeat undelete
swapmark f c ; this should "fix" location of top mark
swapmark
EditFill
; RegionFix - changes the region so it contains balanced delimiters
; It is important to do a RegionFix before any region manipulations.
; Deleting an unfixed region can really mess up the attributes after it!
; Don't call this for a copy, because it might modify the source buffer!
RegionFix: ; I don't need this, fwd declare for other spm/uim files
; I don't need this, fwd declare for other spm/uim files
RegionFixNoMod: ; do as good as you can without changing text for copy
AppendCopy : swapmark 1->append copy togmark
swapmark Unselect 1->AppendNext set markF
AppendDelete : swapmark 1->append delete togmark
Unselect 1->AppendNext set markF
EditFill
RegionCopy : if select {
copy togmark
Unselect
1->AppendNext
}
RegionDelete : if select {
delete togmark
Unselect
1->AppendNext
set markF ; Save position of deletion. Why?
EditFill
}
else DelFwd
RegionErase : if select {
erase togmark
Unselect
0->AppendNext
EditFill
}
else NoBlock
RegionIndent : || tabsize->y ; if no argument, use tabsize
markregion {
while (beforemark) {
if (!isnl) {
tosol past iswhite
column+y TabIndent
}
toeol c
}
}
0->select
RegionOutdent : || tabsize -> x *-1 RegionIndent
RegionEntab : ColTab ; defined in column.uim
RegionDetab : ColDetab
RegionLower :
markregion while beforemark ToLower
RegionUpper :
markregion while beforemark ToUpper
BlockDelete : ColMode ? (if select (ColDelete (aftermark ? swapmark) 0->select) else DelFwd) : RegionDelete
BlockErase : ColMode ? ColErase : RegionErase
BlockCopy : ColMode ? (ColCopy (aftermark ? swapmark) 0->select) : RegionCopy
BlockPaste : ColMode ? ColInsert : UndeleteN
CopyNext : mark (dokey swapmark copy tomark)
DeleteNext : ; delete by next movement command
set markF
delete (dokey if before markF (0->direction))
255->direction
1->AppendNext
EditFill ; repair ASCII paragraph
; This main loop replacement is called when select is turned on. Then
; characters are used to extend the selection:
SelectLoop : ; change to accomodate SearchDirection flag
if (select || ColMode) return ; to prevent recursion and col extend
1->select
while (select=1) {
if stopped {
if (inbuff themark) {
draw key -> int x
if (x = '^M') ('^J'->x)
if (x < ' ' && x!='^J' && x!='^I') {x keypushback dokey}
else if (x>='a' && x<='z' || x>='A' && x<='Z') {
x CharToUpper -> x + 20H -> y
if SearchDirection {
to (current = x || current = y)
c }
else { r to (current = x || current = y) r c } ; added directional sensing
}
else if SearchDirection {x csearch c} ; added directional sensing
else {x r csearch }
}
else dokey
}
else {
AppendNext->append
0->AppendNext
}
}
ToggleColMode :
ColMode ? {
0->ColMode ->flag3
if select (0->select SelectLoop) ; switch to block select mode
}
else {
1->ColMode ->flag3
if select (2->select) ; switch to column select mode
}
ReSelect :
if select (0->select)
else (ColMode ? (2-> select) : SelectLoop) ;toggles select, but with old region
ToggleSelect :
if (!select || (select && !inbuff themark)) {
if !ColMode { ; regular select mode
0->select ; just if mark isn't in buffer
setmark
SelectLoop
}
else ColSetOneEnd ; column select mode
}
else {
0->select draw
}
UndoDelete : to markF BlockPaste ; puts it back in original pos.
#define Thischar ; from Match.spm
#define Matchchar
#define NestLevel
#define OpenDelim
MatchShow :
if beforemark (swapmark c swapmark) ; fix end pos.
else c
1 -> select draw
MatchFind : if (OpenDelim) { ; search forwards
while (NestLevel && !isend) {
c if (current == Thischar) ++NestLevel
if (current == Matchchar) --NestLevel
}
}
else { ; search backwards
while (NestLevel && !(r isend)) {
r c if (current == Thischar) ++NestLevel
if (current == Matchchar) --NestLevel
}
}
MatchSelect :
; Unselect
current case (
'{' 1->OpenDelim '}',
'}' 0->OpenDelim '{',
'(' 1->OpenDelim ')',
')' 0->OpenDelim '(',
'[' 1->OpenDelim ']',
']' 0->OpenDelim '[',
'<' 1->OpenDelim '>',
'>' 0->OpenDelim '<',
$ 0)
-> Matchchar current ->Thischar 1->NestLevel
if (Matchchar) (
if !select (setmark) ; if something's not already lit up, like @foot
MatchFind
if (!isend && !(r isend)) MatchShow
else message "Mis-matched or missing delimiter"
)
else message "\nNot a delimiter"
;----------------------------------------------
; subsection: deletions
;----------------------------------------------
; subsection: Locate, Search & Replace
HiLiteFound : mark (found 1->select draw 0 wait Unselect swapmark)
Locate : set QD Q2 ; extra level of MARK to get around SETMARK
; if (SearchOpt & 1) (mark (to QD mark (toend RegionLower)))
SearchDirection message "\n%[Rev%: Fwd%] Seeking: " QD
mark {
if SearchDirection
(SearchOpt f search QD)
else (SearchOpt r search QD)
? (setmark 1) : (1 Bell message "\n" QD ": not found." 0)
}
LocateNext : Locate -> StrFound
(StrFound && !select) ? {
if !SearchDirection found ; so it works more than once
HiLiteFound
}
: (select && SearchDirection ? found)
LocateFwd : message "\nForward search: " set Q2
if !IsSelect setmark
2 QuoteHack
1->SearchDirection
Locate && !select ? HiLiteFound : (select ? found)
LocateBack :
if !IsSelect setmark
message "\nBackward search: " set Q2 ; used to be Q2
2 QuoteHack
0->SearchDirection
Locate && !select ? (found HiLiteFound)
Find : SearchDirection ? LocateFwd : LocateBack
; didn't want to mess with name for Locate but needed someting
; that responded to rather than set the SearchDir variable.
LocateAuto : if !IsSelect WordSelect
(copy togmark Q2)
if (SearchDirection && beforemark) (swapmark) ; so it skips current word
if (!SearchDirection && aftermark) (swapmark)
Unselect
LocateNext
LocateInc : ; incremental locate macro
set Q2 "" ; use Q2 for CORE compat.
SearchDirection message "\n%[Rev%: Fwd%] Incr. search: " Q2
if !IsSelect set themark ; save start as anchor for LocateNext, except if already selecting something.
infobox "Incremental Locate" {
" As you type, Sprint searches for matching text. ",
" Alt-F, Alt-R change search direction. ^Enter = CR ",
" Esc breaks search at current point. Alt-^H erases. ",
" All other command keys break the search and perform ",
" their expected actions."}
do {
KeyGet ->x
x case { ; how bout ^Q quoting?
1C6h 1->SearchDirection, ; Alt F
1D2h 0->SearchDirection, ; Alt R
18Ah, ; '~^J' CtrlEnter
'^M' '^J'->x mark (to Q2 toend x insert), ; clumsy way to insert some special control Chars
'^J',
'^I' mark (to Q2 toend x insert),
'^A' LocateNext break, ; ^key that normally does LocateNext falls through CASE and gets executed too
188h mark (to Q2 toend r c del), ; remove char. from Q2 was ^H, now Alt Bspace
abortkey,
'^[' break,
; (to themark draw break ),
$ if (x >= 256 || x < 32) (x keyexec break)
else (mark (to Q2 toend x insert)) ; add char. to Q2 search string
}
to themark ; go back to starting point
LocateNext ; and search again
draw ; to show hilite when select =1
}
message "\n"
FWConvert : mark {
if (255 csearch) {
r toend
while (255 csearch) (10 -> current $)
}
else if (r toend '@' csearch) {
r toend
insert "@Style(fill yes)"
10 insert
}
}
$ Bell message "\nDone."
DoRepMenu :
qmenu "Replace this?" {
"Yes" 1,
"No" 0,
"And the rest" 1->GlobalReplace
"Stop" 2,
"Replace and stop" 3
}
ReplaceFwd :
while (SearchOpt search QD) {
1->StrFound ; set to display message
if GlobalReplace {
replace found Q3
++x ; incr number changed
}
else {
mark (1->select found draw setmark)
0->select
DoRepMenu
case {
1 replace found Q3 draw ++x,
2 2->StrFound break,
3 3->StrFound $ replace found Q3 break
}
}
x status "\nReplaced so far: %d..."
}
ReplaceBack :
while (SearchOpt r search QD) {
1->StrFound ; set to display message
if GlobalReplace {
replace found Q3
++x ; incr number changed
}
else {
found mark (1->select found draw setmark)
0->select
DoRepMenu
case {
1 replace found Q3 draw ++x found,
2 2->StrFound break,
3 3->StrFound $ replace found Q3 break
}
}
x status "\nReplaced so far: %d..."
}
doreptest : ; set marks D and E to make unreplace easy
set markD found set markE found
copy (to markE) Q4 $ found r c SearchOpt search QD
replace found Q3
draw
ask "Replace?" ? 2 : 3
DoReplace :
0->StrFound
0->x ; number found
set QD Q2 ; extra level of MARK to get around SETMARK
; ensure that case independant really is, without changing string
if (SearchOpt & 1) (mark (to QD mark (toend RegionLower)))
mark {
if GlobalSearch (r toend f)
status "\nSearching..."
while (SearchOpt search QD) {
1->StrFound ; set to display message
if GlobalReplace {
replace found Q3
++x ; incr number changed
}
else {
mark (1->select found draw setmark)
0->select
qmenu "Replace this?" {
"Test" doreptest,
"Yes" 1,
"No" 0,
"All" 1->GlobalReplace,
"Exit" setmark break ;abort
}
case {
1 replace found Q3 draw ++x,
2 ++x, ; tstrep has done replace, just need to ++x ;; tstrep has done replace; undo it and go on
3 to markD $ replace (to markE) Q4
}
}
x status "\nReplaced so far: %d..."
} ; end while
StrFound
case {
0 message "Not found." 1 Bell,
1 x message "%d replaced.",
2 message "Cancelled."
}
} ; end mark
QueryReplace : ; same as core set, but better messages
if select copy to gmark Q2
else {
do {
message "\nQuery replace search for: " set Q2
if !length Q2 {
error "You must enter a search string."
}
else break
}}
2 QuoteHack
message "\nQuery replace with: " set Q3
3 QuoteHack
0->GlobalReplace
DoReplace
; swapmark ; to fix exit problem
ReplaceAll :
; if NeedSave WantSave
message "\nReplace All search for: " set Q2 $
2 QuoteHack
message "\nReplace All with: " set Q3
3 QuoteHack
1->GlobalReplace
DoReplace
WantSave: ; fwd declare, see Files management
NeedSave:
ReplaceRegion : ; run Quick replace on file region
if IsSelect {
if ColMode (message "\nNot setup for Column replace" break)
if NeedSave WantSave
delete to gmark
;--- now call search and replace
open "" ; put it in unnamed buffer, bigger capacity than Q reg.
clear
undelete
r toend
ReplaceAll ; don't forget, if doing ^J stuff to get 1st ^J
r toend
delete toend
close ; close buffer and return
r c set markF f c ; save position
undelete Unselect
to markF f c ; reposition to save gmark. swapmark?
}
;----------------------------------------------
; subsection: file management
BackUpAndSave : 0 fdelete "%.BAK" 0 fmove "%" "%.BAK" write "%"
QCap : ; uppercase Qx
mark {qswitch while !isend ToUpper}
AllCaps: QCap ; old name
QLow : ; Lowercase Qx
mark {qswitch while !isend ToLower}
QSlash : ; change \\ to / for Tex
-> int x
mark{x qswitch while ('\\' csearch) ( '/'-> current)
}
QMSS : ; add .MSS to filename in Qx if no extension
-> int x
mark {
x qswitch toend
; we must skip past directories, which might have . or .. in them
3 r search "[/\\\\:]"
if !('.' csearch) {insert ".MSS"
}
r toend while !isend ToUpper ; convert name to uppercase
}
QTrim : ; remove leading and trailing blanks, put this in FIle routine
mark {qswitch erase past isgray
toend erase r past isgray }
QWild : mark (qswitch ('*' csearch || ('?' r csearch)))
CheckWild: QWild
QExt : -> int x ; D is 13
set qnumber x fname
mark (x qswitch erase (to current = '.' c) ; remove up to and past '.'
toend insert " " ) ; pad with spaces for testing .c , .p type files
; returns Qreg with spaces if no extension
QStripExt : -> int x ; D is 13
set qnumber x fname
mark{x qswitch to current = '.' erase toend} ; remove extension
; cause fchange "%." doesn't remove period
QTMP : ->x ; creates temp file in home directory, if home is SET
; else temp file will be in current dir. Use with piped, sort, paginate
set qnumber x home ; put home direc. prefix into Q reg. if it exists, requires some care with DOS SET Home=X:\
mark(x qswitch toend insert "TMP.$$$") ; glossqdname handles home var. better
WPConfig : ; word processing assumptions, suppose I don't WANT fill on?
1->WordWrap
0->AutoIndent
TeXConfig : ; TeX assumptions
2->WordWrap
1->AutoIndent ; ?
TEdConfig : ; Text Editing
0->WordWrap
1->AutoIndent
ExtConfig : ; test extension and make some assumptions about editor settings
13 QExt ; returns just extension in QD
if mark(to QD match "MSS") (WPConfig)
else if mark(to QD match "TEX") (TeXConfig)
else if mark(to QD match " ") (WPConfig)
else if mark(to QD match "DOC") (WPConfig)
else if mark(to QD match "SPM") (TEdConfig) ; and so on
else TEdConfig ; default for now
; use this after pickfile and FileOpen, anything that gets to another buffer/file
ExtConfig: ; define as nothing to prevent it from happening. I don't like it now
SetCurrentDir : ; cool
; Set current directory to directory of file in current window
set QD fname
mark {
to QD
toeol
3 r search "[/\\\\]"
if (previous = ':') (f c) ; deal with root dir. by saving slash
erase toeol
}
set cd QD
message "\nCurrent directory set to: "
message cd
FileBack : r bufswitch ExtConfig
FileFwd : bufswitch ExtConfig
FilePick : ; replacement for pickfile primitive
pickfile ExtConfig
FileSave :
0 ->int NoConfirm
if IsUnnamed { ; get a name from the user
do {
set Q0 "" message "\nSave file as: " set Q0
0 QCap 0 QTrim ; added
if (!length Q0)
stopped error "You must give the file a name."
else {
0 QMSS
set Q0 flist Q0 ; force file name validity check
if !(exist Q0) break ; file doesn't exist
else if ask "Overwrite existing file?" {
1-> NoConfirm ; all set, so just do it.
break
}
}
}
0 QMSS
if (NoConfirm || (!(32 exist Q0) || ask "Overwrite existing file?")) {
bufnum->x
if (buffind Q0 && (bufnum != x))
close ;throw away copy if in buffer, and not current file
if !(stopped (write Q0)) {
set fname Q0 ;change file name only if write successful
}
}
}
else { ; to prevent network users from overwriting each other
; check the copy on disk and make sure it has not been
; written by someone else since last saved by user
if (datecheck fname == 1) {
1 Bell
infobox "NETWORK CONFLICT!" {
"\>The file has been written by someone\>",
"\>else on the network. Writing the file\>",
"\>now will overwrite ALL changes made\>",
"\>by the other user.\>",
"_",
"\>To prevent overwriting, CANCEL, then\>",
"\>use 'Write As' to save this to a file\>",
"\>under another name.\>"
}{
if !ask "PRESS ESC or N to CANCEL, Y to SAVE: "
return
}
}
write "%"
}
NeedSave : ; to replace simple modf test
modf
; || (length fname > 0 && !exist fname) )
; modified or named file that's not on disk somehow
; (length fname = 0 && length != 0) ) ; unnamed with something in it
; this test may be TOO thorough
WantSave : ; Used for ExitEditor, FileClose, etc. If modf call this
draw while keypressed (key draw)
if length fname {
message "\nThe file "
message fname
}
else message "\nThis Unnamed file"
if (ask " has not been saved; save it (Y,N,ESC)? ") FileSave
FileTest : ; Q9 normally, preserves FileOpen spec. Returns status code and Q0 with filename in it
-> int x ; takes any register, generalized to maintain Q9 for FileOpen only, and let Q8 be used for FileDelete, etc.
int fstatus 0
x QCap x QTrim ; tex slash, cap the spec, & trim
if (!mark(x qswitch toend 3 match "[\*\?]")) {x QMSS set Q0 qnumber x} ; try to add .mss if it's not a wildcard
if (x QWild) {16 set Q0 flist qnumber x} ; tries to convert wcard to spec, and shows dirs
; result is filename in Q0
if (exist Q0) (1->fstatus)
else {
if (length Q0) 2->fstatus ; flist returned legal spec
else 0->fstatus ; flist returned blank, no wild match
} ; has to be tested with buffind still
fstatus ; returns 1 exist, 2 spec, no file, or 0 no wild spec match
; change all file handling AGAIN to use Q9, not Q0
FWTest : mark {
if (255 csearch) (Bell message "\nFW soft NLs. Run FWConvert")
}
FileGet : -> int fstatus ;ExtConfig is currently disabled, cuz I don't like it
if (buffind Q0) (ExtConfig)
else {
fstatus case (
0 set QD "Can't find " mark(to QD toend insert Q9) error QD,
1 open Q0 ExtConfig FWTest,
2 open Q0 ExtConfig message "\nNew file: " Q0
)
}
FileOpen :
message "\nFile to open: " set Q9
if (!length Q9) open "" else {
SetCurrentDir ;a dubious convenience, that assumes you usually want to open files associated with the current one.
9 FileTest
FileGet
}
FileClose :
if NeedSave WantSave
if (inbuff themark) (0->select) ; turn off select
close
; if !files DefaultRuler
if files ExtConfig
FileConvert : message "\nFile conversion software not installed."
FileDelete :
set QD cdstrip fname
message "\nFile to delete (backspace = " fname "): " set Q8
if !length(Q8) set Q8 fname ; if user hits backspace, use current file
8 FileTest ; returns 1 exist, 2 spec, no file, or 0 no spec, filename in Q0
case (
0 message "\nCan't find " Q8, ; where wild flist returns nothing
2 message "\nCan't find " Q0,
1 {message "\nAre you sure you want to erase " Q0
if (ask "? ") fdelete Q0
if buffind Q0 close
}
)
FileCopy :
set QD cdstrip fname
message "\nFile to copy (backspace = " QD "): " set Q8
if !length(Q8) set Q8 fname ; if user hits backspace, use current file
8 FileTest ; returns 1 exist, 2 spec, no file, or 0 no spec and filename in Q0
case (
0 message "\nCan't find " Q8,
2 message "\nCan't find " Q0,
1 { ; set Q1 ""
message "\nCopy " Q0
message " to: " set Q1
1 QCap 1 QTrim
if (!length Q1) error "You must specify a name."
status "\nCopying..."
fcopy Q0 Q1
message "\nCopy complete."
}
)
FileInsert : ; improved handling of inserted material, makes it easy to delete it.
message "\nFile to insert: " set Q8
8 FileTest ; returns 1 exist, 2 spec, no file, or 0 no spec
case (
0 message "\nCan't find " Q8,
2 message "\nCan't find " Q0,
1 ( if (r !isend) { ; if not at start of file, clumsy fix
r c setmark f c ; adjust point for bad mark placement, so it doesn't get "pushed down" by the insertion
} else setmark ; so it won't save mark correctly at start of file
read Q0
swapmark f c ; this should "fix" location of top mark
swapmark
) ; allow easy removal of insert
)
FileRename : set QD cdstrip fname
message "\nFile to rename or move (backspace = " QD "): " set Q8 ; uses current spec in Q8
if !length(Q8) set Q8 fname ; if user hits backspace, use current file
8 FileTest ; returns 1 exist, 2 spec, no file, or 0 no spec
case (
0 message "\nCan't find " Q8,
2 message "\nCan't find " Q0,
1 { ; set Q1 ""
message "\nRename/move " Q0
message " to: " set Q1
1 QCap 1 QTrim
if (!length Q1) error "You must specify a name."
set Q1 flist Q1
if exist Q1 { ; if file already exists...
message "\nReplace existing " Q1
if !(ask "? ") (message "\nCanceled" abort)
else fdelete Q1
}
fmove Q0 Q1
mark { ; doesn't deal with just the dir name
if buffind Q0 {set fname Q1} ; rename in buffer too
} ; doesn't yet check for same name file in swap file
message "\nRename complete."
}
)
FileCloseAll : bufnum->x
do {
draw
FileClose
} while (bufswitch && bufnum != x)
draw
FileClose
FileSaveAll :
bufnum->x
do {
draw
if NeedSave FileSave
} while (bufswitch && bufnum != x)
draw
if NeedSave FileSave
FileReRead :
if (exist fname) {
line->x
dline->y
clear
$ read fname
x->line
y redraw ; force back to same line
0->select ; make sure select is off
}
else (error "File not on disk (yet).")
RevertToSaved :
if (!modf || ask "Discard changes (Y,N,ESC)? ")
FileReRead
FileWrite :
set Q0 cdstrip fname
message "\nWrite file as: " set Q0
0 QMSS 0 QTrim
if (!(32 exist Q0) || ask "Overwrite existing file?") {
bufnum->x
if (buffind Q0 && (bufnum != x))
close ;throw away copy if in buffer, and not current file
if !(stopped (write Q0)) {
set fname Q0 ;change file name only if write successful
}
}
RegionWrite : ; otta see about appending
if !select (NoBlock return)
set Q0 ""
message "\nName of file to write block to: " set Q0
0 QCap 0 QTrim
if !(mark(to Q0 match "LPT" || match "PRN"))
(0 QMSS) ; if it's not a port .MSS it
if (!(32 exist Q0) || ask "Overwrite existing file? ") {
if !ColMode {
writeregion togmark Q0
mark {
if (buffind Q0) FileReRead ; if file was open, reread
}
}
else {
ColCopy ; get column to QH
mark {
to QH ; get into column buffer
if length (write Q0) ; and write it
if (buffind Q0) FileReRead ; if file was open, re-read
}
}
}
DirectoryNew : set QD cd
if stopped { message "\nChange directory to: " set cd }
set cd QD ; does this save old dir? Push/Pop capability?
DirectoryGoTo : DirectoryNew
PickDirFile :
; Point and shoot open file and set current directory
set Q0 "*.*"
message "\nInsert optional Drive & Dir spec: " set Q0
16 set Q0 flist Q0
open Q0
SetCurrentDir
SetColors :
; set Q0 "spedit.exe" NeedDisk
if (ovlmodf) (ovlwrite "%")
if (2 exist "colors.ovl") (ovlread "colors")
else if (2 exist "colors.uim") (mread "colors") ; change ext.
else (error "Unable to find colors overlay or macros.")
UIWriteAs :
do {
set Q0 "" message "\nSave Editor setup in file: " set Q0
if (!length Q0)
stopped error "You must give the setup file a name."
else if (0 QWild)
stopped error "Wildcards are not allowed."
else {
set Q0 fchange "%.UI" Q0
if (!(32 exist Q0) || ask "Overwrite existing file?") {
ovlwrite Q0
break
}
}
}
UIOpen :
status "\nGetting user interfaces..."
10 set Q0 flist "*.UI"
if (!length Q0) error "No alternate user interfaces found."
if ovlmodf UISave
set Q0 fchange "%.UI" Q0
-1 ovlread Q0
SetEmulation: UIOpen ; compatibility
SetOvlModf : 1->ovlmodf ; force save of changes
SystemCommand :
message "\nDOS command: " set Q5
mark{ to Q5 erase past isgray} ; get rid of any leading spaces
set Q0 "spedit.exe" NeedDisk
draw
if (0 subchar Q5)
; (1+8 call "%comspec% " Q5) ; 4dos
(1 call "command /c" Q5) ;+BIGDOS
else {
exitmessage "--Type EXIT to return to Sprint--\r\n"
SetOvlModf ; save the damn variables
BIGDOS call "command" ; try removing 8, runs restart
}
PipedCommand : ; uEMACS style feature to get redir. output into temp buffer
message "\nPiped command: " set Q5
5 QTrim ; remove blanks
; set Q0 "spedit.exe" NeedDisk draw
if (0 subchar Q5) (
0 QTMP ; create temp file in home dir
status "\nPlease wait..."
call "command /c " Q5 "> " Q0 ; 32 preserves screen
open ""
read Q0 r toend
fdelete Q0
)
FilterCommand : ; uEMACS feature to run filter on current file, beware
if NeedSave WantSave ; strongly recommended
message "\nFilter command: " set Q5
5 QTrim ; remove blanks
; set Q0 "spedit.exe" NeedDisk draw
if (0 subchar Q5) (
0 QTMP ; create temp file in home dir
status "\nPlease wait..."
call "command /c " Q5 "< " fname "> " Q0 ; some redirection, hope it works most of the time
clear ; empty current buffer
; open "" ; open unnamed instead
read Q0 ; put results back in
r toend ; get to start
fdelete Q0 ; kill temp file
)
;----------------------------------------------
; subsection: macro management
; core stuff
; -----------------------------------------------------------------
; Deletions
; -----------------------------------------------------------------
; Variables
; -----------------------------------------------------------------
; Forward Declarations
; -----------------------------------------------------------------
; General Macros
ASCIITable :
call "list f:ascii.txt" ; use list.com to display
CharValue : current ->x message "Char. (%c): " x = "%d " x = "%xh"
; Remarks by Andrew Morrow
; The original EscapeKey would call KeyRecordEnd (who would call
; MacroCollEnd _only_ when recording was ON. Thus, when the keyrecord
; was replayed, the ESC that was the last char in the keyrecord would
; never invoke MacroCollEnd who could decide to replay the keyrecord again.
;
; The fix is to have a unique key to do Macro/Finish and to remove the
; call to KeyRecordEnd from EscapeKey. --I don't understand this at all
; This assumes that the calling macros put a message for display using 'mode'
; Sample : 'Keyboard recording on. Press ESC to end recording.'
MacroCollBegin :
set QF "" ; conflict here with what Gloss does with QF prior to storage, inserting 254s and desc.
if record {
1 Bell message "\nKey recording canceled."
0->record
OldStatLine->statline
}
else {
15->record
statline ->OldStatLine
2->statline
}
MacroCollDo : ; where's this from? What's the point of macrorepcnt
|| 1 -> MacroRepCnt
if record (1 Bell message "\nCurrently recording keys.")
else MacroRepCnt repeat (keypushback QF)
0 -> MacroRepCnt
MacroCollEnd :
if record {
0->record
OldStatLine->statline
draw
}
else if (!MacroRepCnt) MacroCollDo ; don't get what this does.
else {
--MacroRepCnt
if (MacroRepCnt > 0) (keypushback QF)
}
MacroCollHalt : if record MacroCollEnd ; ???
;; Note that .MAC files can be read with 'sp <foo.mac' to redirect input!
MacroCollLoad :
set QD ""
message "\nFile to get recording from: "
set QD
if (!length QD) (set QD "*.MAC") ; to force a list if no entry
set QD cdstrip fchange "%.MAC" QD
13 QCap
if (2 exist QD) {
mark {
to QF
clear
read QD
message "\nRecording loaded."
}
}
MacroCollSave :
set QD flist "%.MAC"
message "\nIn which file should the recording be saved? " set QD
mark {
to QF
write QD
message "\nRecording saved."
}
MacroCollRepeat :
get "How many times" MacroCollDo
MacroLoad : 10 mread flist "*.spm"
MacroRunFile :
set Q0 fname
if (mark (to Q0 1 search ".spm")) {
if (modf=1 || !exist Q0) FileSave
mread fname
}
else (message "\nFile does not have .spm extension.")
; Key macros are mostly dependent on Macro macros
KeyAssignError : stopped error "That key may not be re-assigned."
KeyCanAssign : ; check if the passed key is OK to bind
->int keyin
if (keyin < 20h || keyin > 0ffh)
case {
'^I' 0,
18ah 0,
18dh 0,
'^M' 0,
abortkey 0,
; 10ah 0, ; F10
$ 1
}
else 0 ; Printable Ascii is unassignable
KeyAssign : message "Press key to reassign: "
KeyGet->x if (x == '^[' || x==abortkey) {message "\n" abort}
message "\nEnter macro: "
x macro
KeyAssignMacro :
status "\nTo which key should the macro be assigned: " KeyGet macro
KeyReMap :
draw
infobox "" {
"You may shift commands from one Function",
"or Command key (Alt, Ctrl), to another.",
"_",
"If you press the wrong key as the",
"key to be defined, press it again",
"to cancel the change."
}
do {
status "\nKey to be defined: "
KeyGet->x
if (x KeyCanAssign) {
status "\nWhich key currently performs this command? "
KeyGet keyhelp ; get macro to Q0
if (mark (to Q0 match "text"))
(message "\nSorry, only command keys may be reassigned")
else (x macro Q0) ; make assignment
}
else KeyAssignError
} while (ask "\nReassign another? ")
Meta_ize : -> int ktmp
set QD "" ; clean it from last time
mark { to QD ; dump results in QD
if ktmp < 20h { (ktmp+40h) put " ^%c " }
; Function keys
else if ktmp < 180h { (ktmp-100h) put " F%d "}
; Meta Control keys, shifted by 40h out of control codes
else if ktmp < 1A0h { (ktmp-180h)+40h put " ~^%c "}
; Meta Keys
else { (ktmp-180h) put " ~%c "}
ktmp keyhelp ; keyhelp puts macro name into Q0
TabAction ktmp put "f%xh : "
TabAction insert Q0
}
KeyReport : ; use this to write complete mapping report
int ktmp
message "\nPress a command key "
KeyGet -> ktmp
; if (ktmp < 20h || ktmp > 0ffh) {
ktmp Meta_ize
message "\n" QD
; }
KeyReportAll : ; use this to write complete mapping report
int ktmp 0
set Q8 "KEYBIND.MSS"
8 FileTest FileGet
clear
status "Working ...."
while (ktmp < 200h) {
; use QD scratch reg. and test for Q0 unknown skip
if ktmp = 20h insert "\n"
if ktmp = 180h insert "\n"
if ktmp = 1A0h insert "\n"
if (ktmp <= 20h || ktmp > 0ffh) {
ktmp Meta_ize
insert QD insert "\n"
}
++ktmp
}
KeyRecordMsg :
mode "Keyboard recording on. Use Glossary/Halt to end recording."
; KeyRecordEnd is in Gloss I guess. I think Esc. really doesn't work
MacroExecute :
message "\nEnter macro: " set QG
$ macro QG
KeyAssignMacro : ; in core
message "\nEnter macro: " set QG
status "\nTo which key should the macro be assigned: "
KeyGet->x
if (x = '^[')
abort
if (x KeyCanAssign)
{ x macro QG }
else
KeyAssignError
;#include "gloss.uim"
MacroClear :
if (2 exist "NOTHER.ui") (-2 ovlread "NOTHER.ui")
else if (2 exist "sp.spm") (2 mread "sp.spm")
else error "Macro file SP.SPM not found." ; until I learn command line switches
QuickCard : if ovlmodf (2 ovlwrite "sp") 2 mread "qcard"
;----------------------------------------------
; subsection: window management
ScreenBottom : wlines - 1->dline
ScreenTop : 0->dline while (inruler || isopen) (toeol c)
ScreenCenter : (wlines/2) redraw
ContScrollMsg : message "\nContinuous scroll. Press 0 - 9 to change rate, any other key to stop."
ContScrollDown :
ContScrollMsg
while (!RateChange && line != ++line) (draw RepeatRate ?(RepeatRate wait))
status ""
ContScrollUp :
ContScrollMsg
while (!RateChange && line != --line) (draw RepeatRate ?(RepeatRate wait))
status ""
ScrollRight :
leftedge+40->leftedge
ScrollLeft :
if !leftedge (1 Bell return)
if ((leftedge-40) > 0) (leftedge-40) ->leftedge
else 0->leftedge
ScrollBack : r scroll
ScrollFwd : scroll
ScrollPrevUp : ->x if !(windows=1) {winswitch x ScreenBack r winswitch}
ScrollPrevDown : ->x if !(windows=1) {winswitch x ScreenFwd r winswitch}
WindowBack : r winswitch
ExtConfig
WindowFwd : f winswitch
ExtConfig
WindowClose :
0->zoom
if windows (--windows
ExtConfig)
WindowOpen :
if !zoom ++windows
else {
1 Bell
message "\nNo new windows may be opened while zoomed."
}
WindowCloseAll :
if zoom (--zoom) 1->windows
ExtConfig
WindowDown :
windows repeat {
winswitch
forced (draw)
if !dline (toeol c)
scroll
}
while keypressed key
WindowUp :
windows repeat {
winswitch
forced (draw)
if (dline = wlines - 1) (tosol r c)
r scroll
}
while keypressed key
WindowResize : ; This is a mode
if (windows > 1 && !zoom) {
do {
draw
message "\nPlus (+) and minus (-) resize current window, ESC and ENTER exit."
KeyGet case {
'^M' break,
18dh break,
'^[' break,
'+' ++wlines,
1abh ++wlines,
'-' --wlines,
1adh --wlines,
$ 0 Bell
}
}
status "" ; force status line update
}
else (message "\nCan't resize single window.")
WindowZoom : if (windows > 1) ++zoom $ redraw
;----------------------------------------------
; subsection: direction /unit control
;ToggleDir : Dir ? 0 ->Dir->flag4 -> SearchDirection : 1->Dir->flag4 -> SearchDirection
;DirBack : 0->Dir->flag4 -> SearchDirection
;DirFwd : 1->Dir-> flag4 -> SearchDirection
;ParagraphObject : repeat (Dir ? ParagraphFwd : ParagraphBack)
;SentenceObject : repeat (Dir ? SentenceFwd : SentenceBack)
;WordObject : repeat (Dir ? WordFwd : WordBack)
;int TUnit 'w' ; remember most recent unit of text movement
;TUnitFwd : repeat {
; TUnit case (
; 'c' Right,
; 'w' WordFwd,
; 'l' Down,
; 's' SentenceFwd,
; 'p' ParagraphFwd
; )
; 1->SearchDirection
; }
;
;TUnitBack : repeat {
; TUnit case (
; 'c' Left,
; 'w' WordBack,
; 'l' Up,
; 's' SentenceBack,
; 'p' ParagraphBack
; )
; 0->SearchDirection ; a nice assumption
; }
;
;CharUnit : 'c' -> TUnit -> flag5 draw
;WordUnit : 'w' -> TUnit -> flag5 draw
;LineUnit : 'l' -> TUnit -> flag5 draw
;SentenceUnit : 's' -> TUnit -> flag5 draw
;ParagraphUnit : 'p' -> TUnit -> flag5 draw
;----------------------------------------------
; SECTION: Automatically-called macro definitions (Main, Init,
; EditKey, MenuKey, etc.)
: 1->showkeys
: 50 -> sounddur
: 500->soundfreq
;: TUnit -> flag5
;see main now : BlockCursor
HelpDisk : ; This must preserve Q0 since it has help context!
set QD Q0
set Q0 "sphelp.hlp" NeedDisk
set Q0 QD
;DoHelp :
; HelpDisk
; 2 help Q0
DoHelp : ; whatever is in here is done for 101h code
message "\n" Q0 ; this shows macro in menu choice
EditKey :
KeyGet->int ktmp case {
'^Q' KeyGet + 180h, ; quote
1aah '*', ; PrtScr
1adh '-', ; Grey-
1abh '+', ; Grey+
; 101h 101h, ; F1: help
; 10Ah 0, ; F10: Nothing
140h,144h '^M', ; mouse left key is accept
141h,145h '^[', ; mouse right key is cancel
14ch 150h, ; Make '5' be down arrow if code comes
189h '^I', ; ^I
152h,
18Ah '^J', ; ^J & Ins put in newline
18dh '^M', ; Enter on numpad
'^Z',19bh exitmenus '^[', ; Ctrl/Alt-ESC
abortkey exitmenus '^[',
$ ktmp
}
MenuBind :
do {
status "\nShortcut for menu item: " KeyGet->x
if x = '^[' {0 return} ; if ESC pressed return Null
if (x KeyCanAssign) {
x keypushback
if (x > 255) (0 keypushback)
break
}
else KeyAssignError
}
'^J' return
MenuKey :
KeyGet->int ktmp case {
' ' 150h, ; down
; '^N' 148h, ; up
'^J' MenuBind, ; rebind
189h 148h, ; TabBack: up
'^[' if IsShift (exitmenus 17fh)
else ('^['),
101h 101h, ; F1: dohelp
14ch 150h, ; Make '5' be down arrow if code comes
140h,144h '^M', ; mouse left key is accept
141h,145h '^[', ; mouse right key is cancel
14dh,17fh '^[', ; R. Arrow, keyboard record of ESC feeds back as this
14bh,18dh '^M', ; left Arrow, Enter on numpad
1adh 0->showkeys 0, ; Grey-
1abh 1->showkeys 0, ; Grey+
'^Z',19bh exitmenus '^[', ; Ctrl/Alt-ESC
$ ktmp
}
; Mode variables
; Select, Append, OverWrite, flag3, flag4, flag5, flag6, hour,
; Minute, Hour>=12
; Flag 3 contains the status of 'Column select' mode
; Flag 4 Wrap mode, see usage for WordWrap and Space Insert
NormalMode :
; flags " %2g%[Ins%:Ovr%] %0g%[ %:Sel%] %3g%[ %:Col%] %4g%c/%5g%c"
; flags " %2g%[Ins%:Ovr%] %0g%[ %:Sel%] %3g%[ %:Col%] %4g%[Bck%:Fwd%]"
flags " %4g%[Off%:Wrp%:TeX%] %0g%[ %:Sel%] %3g%[ %:Col%] %7g%11+12#+2u:%02u%[a%:p%]m"
mode ""
; read command-line arguments as file names to open:
GetConfig : ; Set FloppyDisk variable
int numdisks
(hardware "int 11h" & 0c0h)>>6 ->numdisks ; number of floppies - 1
; Drive > ('A'+numdisks) are supposed to be hard
if (0 subchar home) > ('A'+numdisks) 0->FloppyDisk ; Hard-Disk
else if !(exist "spsort.exe") 1->FloppyDisk ; 360ko
else if !(exist "qcard.spm") 2->FloppyDisk ; 720ko
else 3->FloppyDisk ; 1.2Mo
InitScreen : ; This makes the initial "sign-on" screen
; over write core's
ovlmodf->int saveovlmodf
stopped{
statline -> x
0->statline
mark {
to QD clear
version put "%d" toend r (c c)
if (version < 100) "0." else "."
}
open "" draw
infobox "" {
"",
"\>NOTHER Scribe/TeX Compatible\>",
"\>Alternative User Interface\>",
"_",
"\>Sprint Version " QD "\>",
"\>Copyright (c) 1988 Borland International\>",
"\>All Rights Reserved\>",
""
}
{if keypressed (500 delay) else (500 wait)}
} {close x -> statline}
saveovlmodf->ovlmodf
LoadSpeller: ;fwd declare, it's in spell.uim
Init :
ovlmodf -> int OMSave
NormalMode
forced InitScreen ; Show UI sign-on
GetConfig ; Set FloppyDisk variable
if AutoCorrect LoadSpeller ; if required, load speller
set QA "STANDARD.SPG" ; default glossary name (if used)
set QJ "SPELLER AMERICAN.LX1 USER.LX2" ; standard speller
set QK "\xff\xff\xff" ; empty Spmerge menu data
OMSave ->ovlmodf
InitArg :
if (n < 6) (++n->windows)
; Just to prevent seeing an existing file in a buffer when a starname
; is given from the command line, we do the following:
; if (0 QWild) {
; open "" ; force user to select filename commented out
; draw }
set Q9 Q0
9 FileTest ; returns 1 exist, 2 spec, no file, or 0 no spec
FileGet
; The following macro is run every time Sprint starts up. It is called from
; main, before any other processing. This means, that regardless of how the
; editor was started (init, or via restart macro), all variables are sure to be
; reset to their defaults. Users may add any other variable initialization
; to this macro.
ResetDefaults :
0->n ; n=count of command-line files
->ColMode
->flag3 ; Col mode flag
1->statline
2 ->scrollborder
3 ->SearchOpt ; FinalWord uses wild card searches?
'^['->abortkey
InsertMode ->overwrite ; restore old overwrite mode
; Note: main do loop is executed for *every* key, including letters.
; Don't make it too complicated or it will slow down maximum typing
; speed!
Main :
ResetDefaults ; initialize all vars here.
BlockCursor ; make sure it's on
stopped { ; so user can't abort while checking file dates.
if !files (stopped DefaultRuler) ; make sure files have rulers
else {
bufnum -> x
do { ; read any files that have newer versions
stopped ; to disable abortcheck in loop
if (!modf && (datecheck fname == 1)) { ; newer version of file; used to be > 0
clear
read fname
r toend
}
bufswitch
} while bufnum!=x
}
}
do {
if stopped dokey
else {
; QuickFill
AppendNext->append
0->AppendNext
}
}
; This macro is called when -r is passed to the editor. The editor does
; that itself when it reloads after calling the formatter to do a pagination
; operation. This is controlled by the 8 bit in the argument to the
; "call spfmt" macro. See Paginate.
; removed conversion code, added restart code for faster previewing with TeX
; RDT, 4/8/91
Restart :
-> ReturnCode
NormalMode
if (exist "log.$$$") { ; paginated, need to fix for network
draw pageread "log.$$$"
fdelete "log.$$$"
}
while keypressed key ; eliminate type-ahead
; otta have home var. inserted here for network users
GlossSave: ;fwd declare, it follows in gloss.uim
ExitEditor : bufnum->x
do {
if NeedSave WantSave
else if (IsUnnamed && IsOnlyRuler) {
(if (bufnum==x) (close bufnum->x) else close)
}
} while (bufswitch && bufnum != x)
EraseSwap || !files -> killswap
; set Q0 "spedit.exe" NeedDisk
GlossSave ; save glossary if in use
SetOvlModf ; save variables always, use resetdefaults to counteract
exit
;## end