home *** CD-ROM | disk | FTP | other *** search
- /* -----------------------------------------------------------------------------
-
- ApiLib ©1995 Dietmar Eilert
-
- Mirror API client, ©1995 Dietmar Eilert. Highlights matching bracket if cursor
- is moved over a bracket.
-
- Dice:
-
- DMAKE
-
- -------------------------------------------------------------------------------
-
- */
-
- #include "defs.h"
-
- /// "Prototype"
-
- // library functions
-
- Prototype LibCall struct APIClient *APIMountClient(__A0 struct APIMessage *, __A1 char *);
- Prototype LibCall void APICloseClient(__A0 struct APIClient *, __A1 struct APIMessage *);
- Prototype LibCall void APIBriefClient(__A0 struct APIClient *, __A1 struct APIMessage *);
- Prototype LibCall void APIFree (__A0 struct APIClient *, __A1 struct APIOrder *);
-
- // private functions
-
- Prototype void Dispatch(struct APIMessage *);
- Prototype BOOL FindMarkedBracket(struct EditConfig *);
- Prototype BOOL NoUserBlock (struct EditConfig *);
- Prototype BOOL IsABracket(UWORD);
- Prototype BOOL MatchingBracket(struct APIMessage *, UWORD);
-
- // the following line determines if online checks are enabled
-
- #undef ONLINECHECK
-
- ///
- /// "library functions"
-
- LibCall struct APIClient *
- APIMountClient(__A0 struct APIMessage *apiMsg, __A1 char *args)
- {
- static struct APIClient apiClient;
-
- apiClient.api_APIVersion = API_INTERFACE_VERSION;
- apiClient.api_Version = 3;
- apiClient.api_Name = "Mirror API";
- apiClient.api_Info = "Bracket highlighting";
- apiClient.api_Commands = NULL;
- apiClient.api_Serial = 0;
- apiClient.api_Classes = API_CLASS_SYSTEM | API_CLASS_KEY;
- apiClient.api_Area = NULL;
-
- return(&apiClient);
- }
-
- LibCall void
- APICloseClient(__A0 struct APIClient *handle, __A1 struct APIMessage *apiMsg)
- {
- // no ressources to be freed
- }
-
- LibCall void
- APIBriefClient(__A0 struct APIClient *handle, __A1 struct APIMessage *apiMsg)
- {
- struct APIMessage *msg;
-
- // handle host's command notify
-
- for (msg = apiMsg; msg; msg = msg->api_Next) {
-
- if (msg->api_State == API_STATE_NOTIFY) {
-
- switch (msg->api_Class) {
-
- case API_CLASS_KEY:
-
- Dispatch(msg);
-
- case API_CLASS_SYSTEM:
-
- break;
-
- default:
-
- msg->api_Error = API_ERROR_UNKNOWN;
- }
- }
- }
- }
-
- LibCall void
- APIFree(__A0 struct APIClient *handle, __A1 struct APIOrder *apiOrder)
- {
- // no ressources to be freed
- }
-
- ///
- /// "private functions"
-
- /* --------------------------------- Dispatch ----------------------------------
-
- Dispatch incoming API event
-
- */
-
- void
- Dispatch(apiMsg)
-
- struct APIMessage *apiMsg;
- {
- struct EditConfig *config = (struct EditConfig *)apiMsg->api_Instance->api_Environment;
-
- if (apiMsg->api_Action == API_ACTION_RAWKEY) {
-
- UWORD ascii = config->CurrentBuffer[config->Column];
-
- if (IsABracket(ascii) && NoUserBlock(config)) {
-
- if (MatchingBracket(apiMsg, ascii) == FALSE) {
-
- if (FindMarkedBracket(config))
-
- apiMsg->api_Refresh |= API_REFRESH_NOMARKER;
- }
- }
- else if (FindMarkedBracket(config))
-
- apiMsg->api_Refresh |= API_REFRESH_NOMARKER;
- }
- else if (apiMsg->api_Action == API_ACTION_VANILLAKEY) {
-
- if (NoUserBlock(config)) {
-
- // check char under cursor
-
- UWORD ascii = config->CurrentBuffer[config->Column];
-
- if (IsABracket(ascii)) {
-
- if (MatchingBracket(apiMsg, ascii) == FALSE) {
-
- if (FindMarkedBracket(config))
-
- apiMsg->api_Refresh |= API_REFRESH_NOMARKER;
- }
- }
-
- #ifdef ONLINECHECK
-
- else if (config->Column) {
-
- ascii = (UWORD)apiMsg->api_Data;
-
- // check character next to cursor
-
- --config->Column;
-
- // just typed by user ?
-
- if (config->CurrentBuffer[config->Column] == ascii) {
-
- if (MatchingBracket(apiMsg, ascii) == FALSE)
-
- if (FindMarkedBracket(config))
-
- apiMsg->api_Refresh |= API_REFRESH_NOMARKER;
- }
- else if (FindMarkedBracket(config))
-
- apiMsg->api_Refresh |= API_REFRESH_NOMARKER;
-
- ++config->Column;
- }
-
- #endif
-
- else if (FindMarkedBracket(config))
-
- apiMsg->api_Refresh |= API_REFRESH_NOMARKER;
- }
- }
- }
-
-
- /* ------------------------------- MatchingBracket -----------------------------
-
- Find matching bracket. Ignore opening brackets preceeded by '/' (ASCII 92, TeX
- style construction used to insert a bracket into text).
-
- \} ............ ignored (TEX constant)
- \\} ........... not ignored (TEX bracket)
-
- */
-
- BOOL
- MatchingBracket(apiMsg, examine)
-
- struct APIMessage *apiMsg;
- UWORD examine;
- {
- UBYTE *known;
- WORD step;
-
- for (step = 1, known = "(){}"; *known; ++known, step = -step) {
-
- if (examine == *known) {
-
- WORD column;
- UBYTE *current;
- BOOL isTEX;
-
- struct EditConfig *config = (struct EditConfig *)apiMsg->api_Instance->api_Environment;
-
- column = config->Column;
- current = config->CurrentBuffer;
-
- if ((column > 0) && (current[column - 1] == 92)) {
-
- if ((column > 1) && (current[column - 2] == 92))
- isTEX = FALSE;
- else
- isTEX = TRUE;
- }
- else
- isTEX = FALSE;
-
- if (isTEX == FALSE) {
-
- WORD len, level, count, distance;
- BOOL success, inString;
- ULONG line;
- UBYTE twin;
-
- inString = FALSE;
- success = FALSE;
-
- line = config->Line;
- len = config->CurrentLen;
-
- twin = *(known + step);
-
- count = 0;
- level = -1;
-
- // modify the scan depth (default: 50 lines) to speed up the client
-
- for (distance = 0; distance <= 50; ++distance) {
-
- while ((column >= 0) && (column < len)) {
-
- UBYTE *next = current + column;
-
- if ((*next == 34) || (*next == 39))
-
- inString = !inString;
-
- else if (!inString) {
-
- if ((column > 0) && (*(next - 1) == 92)) {
-
- if ((column > 1) && (*(next - 2) == 92))
- isTEX = FALSE;
- else
- isTEX = TRUE;
- }
- else
- isTEX = FALSE;
-
- if (!isTEX) {
-
- if (*next == twin) {
-
- if (level)
- --level;
-
- else {
-
- success = TRUE;
- break;
- }
- }
- else if (*next == *known) {
-
- ++level;
- ++count;
- }
- }
- }
-
- column += step;
- }
-
- if (success) {
-
- BOOL adjacent = FALSE;
-
- if (line == config->Line)
-
- adjacent = (column == (config->Column + step));
-
- if (adjacent)
-
- apiMsg->api_Refresh |= API_REFRESH_NOMARKER;
-
- else {
-
- // block markers may not be used in fold headers
-
- if (GET_FOLD(config->TextNodes + line))
-
- return(FALSE);
-
- else {
-
- if ((distance == 0) && ((config->Marker == BLOCKMODE_NONE) || ((line == config->BlockStartY) && (line == config->BlockEndY))))
-
- apiMsg->api_Refresh = API_REFRESH_LINE;
-
- else if (config->Marker == BLOCKMODE_NONE)
-
- apiMsg->api_Refresh = API_REFRESH_MARKER;
- else
- apiMsg->api_Refresh = API_REFRESH_DISPLAY;
-
- config->Marker = BLOCKMODE_CHAR;
-
- config->BlockStartX = config->BlockEndX = column;
- config->BlockStartY = config->BlockEndY = line;
-
- return(TRUE);
- }
- }
- }
- else {
-
- line += step;
- inString = FALSE;
-
- if ((line >= 0) && (line < config->Lines)) {
-
- struct LineNode *lineNode = config->TextNodes + line;
-
- current = lineNode->Text;
- len = lineNode->Len;
-
- column = (step == -1) ? len - 1 : 0;
- }
- else // no matching bracket
- break;
- }
- }
-
- break;
- }
- }
- }
-
- return(FALSE);
- }
-
-
- /* ------------------------------- NoUserBlock ---------------------------------
-
- Return TRUE if there is no user-defined block, i.e. either no block at all or a
- marked bracket only (possibly marked by us).
-
- */
-
- BOOL
- NoUserBlock(config)
-
- struct EditConfig *config;
- {
- return((config->Marker == BLOCKMODE_NONE) || FindMarkedBracket(config));
- }
-
-
- /* ----------------------------- FindMarkedBracket -----------------------------
-
- Return TRUE if a single bracket has been marked (probably by us)
-
- */
-
- BOOL
- FindMarkedBracket(config)
-
- struct EditConfig *config;
- {
- if (config->Marker == BLOCKMODE_CHAR) {
-
- if (config->BlockStartY == config->BlockEndY) {
-
- if (config->BlockStartX == config->BlockEndX) {
-
- UWORD pos = config->BlockStartX;
-
- if (config->BlockStartY == config->Line) {
-
- if (pos < config->CurrentLen)
-
- return(IsABracket(config->CurrentBuffer[pos]));
- }
- else {
-
- struct LineNode *lineNode = config->TextNodes + config->BlockStartY;
-
- if (pos < lineNode->Len)
-
- return(IsABracket(lineNode->Text[config->BlockStartX]));
- }
- }
- }
- }
-
- return(FALSE);
- }
-
- /* -------------------------------- IsABracket ---------------------------------
-
- Check whether character is a bracket
-
- */
-
- BOOL
- IsABracket(letter)
-
- UWORD letter;
- {
- if (letter == '(')
- return(TRUE);
-
- if (letter == ')')
- return(TRUE);
-
- if (letter == '{')
- return(TRUE);
-
- if (letter == '}')
- return(TRUE);
-
- return(FALSE);
- }
-
- ///
-