-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Syntax highlighting categories #21
Comments
Possibly of use: I see that the QuickBasic manual breaks its statements into the following groups:
I do not know if these categories overlap or if they have any relationship to what is actually used in syntax highlighting systems. I will say that I think it is a very good feature that basic-mode makes control-flow distinct. Update: after reading through that chapter, I think it actually contains some very useful divisions for syntax highlighting and it is not too different from how basic-mode currently works. In particular, Control-Flow (GOTO, IF...THEN, FOR..NEXT) is fundamental to BASIC programmers and is already prominently shown. Less common, but perhaps even more important to shine a spotlight on are the Trapping Statements (ON ERR GOTO...) which can change a program's flow of control asynchronously. (For example, Statements Used in Procedures (SUB, FUNCTION, DEF FN) are also currently shown in the same face as Control-Flow, but if there are any spare font-lock categories left, it may look better if they were subtly different. I do not have problem with mushing together Standard I/O and File I/O and Graphics Statements, but I'm not opposed to keeping them separate as the QuickBasic manual has them either. String-Processing Functions do make some sense to show with a slight variation from normal statements, but I do not know if it is worth going out of the way to do. |
Samples of other syntax highlighting for BASIC: Github GFMGithub's MarkDown attempts to syntax highlight fenced code blocks. For example:
Becomes, 0 DEFINT X=32768, Y=RND(-1) ' SALT
10 PRINT "HELLO, WORLD! "; TIME$;
20 Y=(31*Y+PEEK(X)) MOD 257: REM PRIME HASH
30 X=X+1: GOSUB 10
Telnet23's language-basicGithub actually relies on telnet23's language-basic syntax highlighting. Like basic-mode.el, it properly marks control-flow as being important. Unfortunately, the way Github has used it, control-flow and operators are both shown in red, so in practice, control-flow is not distinct. One feature it has that basic-mode.el should The main categories appear to be BASIC's typical functions, statements, and operators, but interestingly, it separates string functions from other functions. I suppose the reasoning is that it shows the type the function is returning. Is that an idea that would be helpful to programmers? The regexps are succinctly defined in .CSON format: Click to see the regexpsscopeName: 'source.basic'
name: 'BASIC'
fileTypes: [ 'bas' ]
patterns: [
{
# line number definition
match: '^\\s*\\d+'
name: 'entity.name.tag.basic'
}
{
# line number reference
match: '\\b((?i)THEN|ELSE|GO\\s*TO|GOSUB)\\s*(\\d+)'
captures:
1: name: 'keyword.control.basic'
2: name: 'entity.name.tag.basic'
}
{
# number
match: '\\b(?:\\d\\.|\\d+\\.\\d+|\\.\\d+|\\d+)(?:[Ee][-+]?\\d+)?\\b'
name: 'constant.numeric.basic'
}
{
# string
match: '"[^"]*"'
name: 'string.quoted.double.basic'
}
{
# comment
match: '(?i:REM.*)'
name: 'comment.line.basic'
}
{
# flow control statement
match: '\\b(?i:FOR|TO|NEXT|IF|THEN|ELSE|GO\\s*TO|GOSUB|RETURN)\\b'
name: 'keyword.control.basic'
}
{
# other statement
match: '\\b(?i:\\?|\\&|\\!|\'|ABSOLUTE|ACCESS|AS|BASE|BEEP|BLOAD|BSAVE|CALL|CASE|CHAIN|CHDIR|CIRCLE|CLEAR|CLOSE|CLS|COLOR|COM|COMMON|CONST|DATA|DECLARE|DEF|DEFDBL|DEFINT|DEFLNG|DEFSNG|DEFSTR|DIM|DO|DRAW|END|ENVIRON|ERASE|ERROR|EXIT|FIELD|FILES|FUNCTION|GET|HOME|IF|INPUT|INPUT#|IOCTL|KEY|KILL|LET|LINE|LOCATE|LOCK|LOOP|LPRINT|LSET|MKDIR|NAME|NEW|ON|OPEN|OPTION|OUT|PAINT|PALETTE|PCLEAR0|PCLEAR1|PCOPY|PEN|PLAY|PMAP|PMODE0|POKE|PRESET|PRINT|PRINT#|PSET|PUT|RANDOMIZE|READ|REDIM|REM|RESET|RESTORE|RESUME|RMDIR|RSET|RUN|SCREEN|SEEK|SELECT|SHARED|SHELL|SLEEP|SOUND|SOUNDRND|STATIC|STOP|STRIG|SUB|SWAP|SYSTEM|TIMER|TROFF|TRON|TYPE|UNLOCK|USING|VIEW|WAIT|WEND|WHILE|WINDOW|WRITE)\\b'
name: 'entity.name.type.basic'
}
{
# string function
match: '\\b(?i:BIN|CHR|COMMAND|DATE|ENVIRON|ERDEV|HEX|INKEY|INPUT|IOCTL|LAFT|LCASES|LEFT|LTRIM|MID|MKD|MKDMBF|MKI|MKL|MKS|MKSMBF|OCT|RIGHT|RTRIM|SPACE|SPC|STR|STRING|TAB|TIME|UCASE|UPS|VARPTR)\\$'
name: 'entity.name.function.basic'
}
{
# non-string function
match: '\\b(?i:ABS|ASC|ATN|BRK|CDBL|CINT|CLNG|COS|CSNG|CSRLIN|CTL|CVD|CVDMBF|CVI|CVL|CVS|CVSMBF|D2R|EOF|ERDEV|ERL|ERR|EXP|FILEATTR|FIX|FRE|FREEFILE|HEIGHT|INP|INSTR|INT|ITM|LBOUND|LEN|LG|LIN|LN|LOC|LOF|LOG|LOG10|LPOS|NINT|NUM|PEEK|PEN|POINT|POS|R2D|REC|RND|SADD|SCREEN|SEEK|SETMEM|SGN|SIN|SPA|SPC|SQR|SQRT|STICK|STRIG|SYS|TAB|TAN|TIM|TIMER|TYP|UBOUND|VAL|VALPTR|VALSEG|VARPTR|VARSEG|WIDTH)\\b'
name: 'entity.name.function.basic'
}
# {
# # other function
# match: '\\b(\\w+[\\$%!]?)\\('
# captures:
# 1: name: 'entity.name.function.basic'
# }
{
# operator
match: '\\^|\\+|-|\\*\\*|\\*|/|=|<>|<=|=<|>=|=>|<|>|\\b(?i:MOD|NOT|AND|OR)\\b'
name: 'keyword.operator.basic'
}
] KATE editor |
Just for reference, here are the categories into which Bill Crider's “BASIC Programming Conversion” puts the reserved words from several dialects of BASIC. Actually, "tags" would be a better description, as each word can fit in multiple boxes.
Crider says that he is covering BASIC for "Apple, IBM PC, IBM PCjr, Commodore 64, TRS-80 Model III, and TRS-80 Color Computer". However, I noticed that his list of all 551 reserved words one should avoid using in identifiers as they are defined in one BASIC or another actually includes more keywords than were listed in the categories above. They appear to be from Atari BASIC (e.g., ABS
ACS
ACSD
ACSG
ADR
AND
APPEND
ARCOS
ARCSIN
ARCTAN
ASC
ASCII
ASN
ASND
ASNG
AT
ATAN
ATN
ATND
ATNG
AUDIO
AUTO
AXIS
B-A:
B-F:
B-P:
B-R:
B-W:
BACKUP
BAPPEN
BASE
BEEP
BGET
BLOAD
BLOCK-ALLOCATE:
BLOCK-EXECUTE:
BLOCK-FREE:
BLOCK-READ:
BLOCK-WRITE:
BUFFER-POINTER
BOLD
BPUT
BREAK
BRIGHTNESS
BSAVE
BUTTON
BYE
CALL
CATALOG
CDBL
CH
CHAIN
CHANGE
CHAR
CHAR$
CHARSIZE
CHDIR
CHR
CHR$
CINT
CIRCLE
CLEAR
CLG
CLK$
CLK
CLOAD
CLOADM
CLOCK
CLOG
CLOSE
CLR
CLRDOT
CLS
CMD
CO
CODE
COLLECT
COLOR
COLOR=
COM
COMMON
CON
CONCAT
CONSOLE
CONT
COPY
COS
COSD
COSG
COSH
COUNT
CSAVE
CSAVEM
CSH
CSNG
CSRLIN
CUR
CVD
CVI
CVN
CVS
CVT$%
CVT$F
CVT%$
CVTF$
DASH
DAT
DATA
DATE$
DCLOSE
DEBUG
DEF
DEFDBL
DEFFN
DEFINT
DEF SEG
DEFSNG
DEFSTR
DEFUSR
DEG
DEGREE
DEL
DELETE
DET
DIGITS
DIM
DIR
DIRECTORY
DLOAD
DLOADM
DMS
DOPEN
DOS
DOT
DRAW
DRAWTO
DRIVE
DS
DSAVE
DSKI$
DSKINI
DSKO$
DSP
EDIT
ELSE
END
ENTER
ENVIRON
ENVIRON$
EOF
EQ
EQV
ERASE
ERDEV
ERDEV$
ERL
ERR
ERRL
ERRN
ERROR
ERRS$
EXAM
EXCHANGE
EXEC
EXIT
EXP
EXT
FDIM
FETCH
FGET
FIELD
FIF
FILE
FILES
FILL
FIN
FIND
FINPUT
FIX
FLASH
FLOW
FLT
FMT
FN
FNEND
FONT
FOR
FORMAT
FOUT
FPRINT
FPUT
FRAC
FRE
FREE
FUNTIL
FUZZ
GE
GET
GET#
GIN
GO
GO TO
GOODBYE
GOSUB
GOSUB-OF
GOT
GOTO
GOTO-OF
GR
GRAD
GRAPHICS
GT
HCOLOR
HCOLOR=
HEADER
HEX$
HGR
HGR2
HIMEM:
HLIN
HLIN-AT
HOME
HPLOT
HSCRN
HTAB
IF
IF-GOT
IF-GOTO
IF-LET
IF-THE
IF-THEN
IF-THEN-ELSE
IMAGE
IMP
IN#
INCH
INCHAR
INDEX
INIT
INKEY$
INP
INPUT
INPUT#
INPUT$
INPUT1
INPUTLINE
INSTR
INT
INTER$
INVERSE
IOCTL
IOCTL$
JOYSTK
KEY
KEY$
KILL
LE
LEFT
LEFT$
LEN
LET
LGT
LI
LIN
LINE
LINE INPUT#
LINEINPUT
LINK
LINPUT
LIS
LIST
LLIST
LN
LOAD
LOADM
LOC
LOCATE
LOF
LOG
LOG10
LOGE
LOMEM:
LPOS
LPRINT
LPRINTUSING
LSET
LT
M-E:
M-R:
M-W:
MAN
MARK
MAT *
MAT +
MAT -
MAT =
MAT CON
MAT IDN
MAT INPUT
MAT INV
MAT PRINT
MAT READ
MAT TRN
MAT ZER
MAX
MDD
MEM
MEMORY-EXECUTE:
MEMORY-READ:
MEMORY-WRITE:
MERGE
MID
MID$
MIN
MKD$
MKDIR
MKI$
MKN$
MKS$
MOD
MONITOR
MOTOR
MPY
MTPACK
NAME
NE
NEW
NEX
NEXT
NOFLOW
NOISE
NORMAL
NOT
NOTE
NOTRACE
NULL
NUM
NUM$
OCT$
OFF
OLD
ON
ON ERR GOTO
ON ERROR GOTO
ON-GOSUB
ON-GOT
ON-GOTO
ONERR
OPEN
OPTION
OPTION BASE
OR
OUT
OUTPUT
PADDLE
PAGE
PAINT
PALETTE
PALETTE USING
PAUSE
PCLEAR
PCLS
PCOPY
PDL
PEEK
PEN
PI
PIN
PLAY
PLOT
PMAP
PMODE
POINT
POINTER
POKE
POLL
POP
POS
POSITION
POSN
PPOINT
PR#
PRECISION
PRESET
PRI
PRINT
PRINT #USING
PRINT AT
PRINT USING
PRINT #
PRINT @
PSET
PTR
PTRIG
PUT
PUT#
RAD
RADIAN
RAN
RANDOM
RANDOMIZE
RBYTE
RDRAW
REA
READ
READ#
RECALL
RECORD
REM
REMARK
REN
RENAME
RENUM
RENUMBER
REP
REPEAT$
RES
RESET
RESTORE
RESUME
RESUME NEXT
RET
RETURN
RIGHT
RIGHT$
RMDIR
RMOVE
RND
ROT=
ROTATE
ROW
RSET
RU
RUN
SAVE
SAVEM
SCALE
SCALE=
SCR
SCRATCH
SCREEN
SCRN
SCRN(
SECRET
SEG
SEG$
SET
SETCOLOR
SETDOT
SGET
SGN
SHELL
SHLOAD
SHUT
SIN
SIND
SING
SINH
SKIPF
SLEEP
SNH
SORT
SOUND
SPA
SPACE
SPACE$
SPC
SPC(
SPEED=
SPUT
SQR
SQRT
ST
STATUS
STE
STEP
STICK
STO
STOP
STORE
STR
STR$
STRIG
STRING
STRING$
STUFF
SUB
SUBEND
SUM
SWAP
SYS
SYSTEM
TAB
TAB(
TAN
TAND
TANG
TANH
TAPPEND
TEXT
THE
THEN
TI
TI$
TIM
TIME
TIME$
TIMER
TLIST
TLOAD
TNH
TO
TOP
TRACE
TRACE OFF
TRACE ON
TRAP
TROFF
TRON
TSAVE
TYP
TYPE
UNLOAD
UNTIL
USER
USING
USR
VAL
VARPTR
VARPTR$
VERIFY
VIEW
VIEWPORT
VLIN
VLIN-AT
VPOS
VTAB
WAIT
WBYTE
WEAVE
WEND
WHILE
WIDTH
WINDOW
WRITE
WRITE#
XDRAW
XIO
XOR
XPLOT
XRA |
It is also possible to create new font-lock categories. I don't know if that is considered good style though. One could do something like this: (defface font-lock-operator-face
'((((class grayscale) (background light)) :foreground "Gray90" :weight bold)
(((class grayscale) (background dark)) :foreground "DimGray" :weight bold)
(((class color) (min-colors 88) (background light)) :foreground "ForestGreen")
(((class color) (min-colors 88) (background dark)) :foreground "PaleGreen")
(((class color) (min-colors 16) (background light)) :foreground "ForestGreen")
(((class color) (min-colors 16) (background dark)) :foreground "PaleGreen")
(((class color) (min-colors 8)) :foreground "green")
(t :weight bold :underline t))
"Font Lock mode face used to highlight operators."
:group 'font-lock-faces)
(defvar font-lock-operator-face 'font-lock-operator-face
"Face name to use for operators.") |
This is a good idea. But maybe it should be a separate issue, because it has nothing to do with highlighting categories? |
I like that idea. I also don't know about the style guidelines, but I think it should be fine since it would only affect BASIC mode. Creating new categories and aliasing the existing ones (functions/keywords/builtins) would allow categories that make sense for BASIC. I think the QBASIC manual is a good starting point, but I'd suggest merging some of the similar categories:
Of course, the categories from that particular appendix are not exhaustive as they do not cover the more day-to-day categories:
Click to see the full list of QBASIC reserved words.ABS
ACCESS
ALIAS
AND
ANY
APPEND
AS
ASC
ATN
BASE
BEEP
BINARY
BLOAD
BSAVE
BYVAL
CALL
CALLS
CASE
CDBL
CDECL
CHAIN
CHDIR
CHR$
CINT
CIRCLE
CLEAR
CLNG
CLOSE
CLS
COLOR
COM
COMMANDS
COMMON
CONST
COS
CSNG
CSRLIN
CVD
CVDMBF
CVI
CVL
CVS
CVSMBF
DATA
DATES
DECLARE
DEF
DEFDBL
DEFINT
DEFLNG
DEFSNG
DEFSTR
DIM
DO
DOUBLE
DRAW
ELSE
ELSEIF
END
ENDIF
ENVIRON
ENVIRONS
EOF
EQV
ERASE
ERDEV
ERDEVS
ERL
ERR
ERROR
EXIT
EXP
FIELD
FILEATTR
FILES
FIX
FOR
FRE
FREEFILE
FUNCTION
GET
GOSUB
GOTO
HEX$
IF
IMP
INKEYS
INP
INPUT
INPUTS
INSTR
INT
INTEGER
IOCTL
IOCTLS
IS
KEY
KILL
LBOUND
LCASES
LEFTS
LEN
LET
LINE
LIST
LOC
LOCAL
LOCATE
LOCK
LOF
LOG
LONG
LOOP
LPOS
LPRINT
LSET
LTRIMS
MID$
MKD$
MKDIR
MKDMBFS
MKI$
MKL$
MKSMBFS
MKSS
MOD
NAME
NEXT
NOT
OCT$
OFF
ON
OPEN
OPTION
OR
OUT
OUTPUT
PAINT
PALETTE
PCOPY
PEEK
PEN
PLAY
PMAP
POINT
POKE
POS
PRESET
PRINT
PSET
PUT
RANDOM
RANDOMIZE
READ
REDIM
REM
RESET
RESTORE
RESUME
RETURN
RIGHTS
RMDIR
RND
RSET
RTRIMS
RUN
SADD
SCREEN
SEEK
SEG
SELECT
SETMEM
SGN
SHARED
SHELL
SIGNAL
SIN
SINGLE
SLEEP
SOUND
SPACES
SPC
SQR
STATIC
STEP
STICK
STOP
STR$
STRIG
STRING
STRINGS
SUB
SWAP
SYSTEM
TAB
TAN
THEN
TIMER
TIMES
TO
TROFF
TRON
TYPE
UBOUND
UCASES
UEVENT
UNLOCK
UNTIL
USING
VAL
VARPTR
VARPTRS
VARSEG
VIEW
WAIT
WEND
WHILE
WIDTH
WINDOW
WRITE
XOR |
What are the conventions for syntax highlighting of BASIC code? While working on issue #20 (derived modes), I have run into a problem that I do not know the meaning of groupings like basic-builtin-regexp and basic-keyword-regexp.
If there is a "typical" convention, it would be helpful to have it in the comments in basic-mode.el. If there is not, and I suspect there isn't yet, it may be good to see what others have done and look at what makes sense.
Note that not all of the categories are confusing. Comments, constants, strings, and so on are self-explanatory. The ones that I'd like to get nailed down are:
SIN()
) which return a value. The definition of it makes sense, but there is some question about whether things likePEEK()
andTIME$
belong. And is this distinction even helpful to a programmer?AS
andRANDOMIZE
. And wouldn't it make more sense for data type declarations likeDEFINT
to be highlighted as a type?PRINT
,PEEK
,POKE
, etc. But there are several counter examples to that idea.DATA
andLET
seem to be more structural.AND
,MOD
,NOT
,OR
, andXOR
are operators and I would have expected them to be highlighted differently.The text was updated successfully, but these errors were encountered: