1 | // LispEditorView.cpp : implementation of the CLispEditorView class
|
---|
2 | //
|
---|
3 |
|
---|
4 | #include "stdafx.h"
|
---|
5 | #include "LispEditor.h"
|
---|
6 | #include "MainFrm.h"
|
---|
7 |
|
---|
8 | #include "LispEditorDoc.h"
|
---|
9 | #include "CntrItem.h"
|
---|
10 | #include "LispEditorView.h"
|
---|
11 |
|
---|
12 | #ifdef _DEBUG
|
---|
13 | #define new DEBUG_NEW
|
---|
14 | #undef THIS_FILE
|
---|
15 | static char THIS_FILE[] = __FILE__;
|
---|
16 | #endif
|
---|
17 |
|
---|
18 | enum {
|
---|
19 | LISP_SYMBOL,
|
---|
20 | LISP_NUMBER,
|
---|
21 | LISP_STRING,
|
---|
22 | LISP_OPERATOR,
|
---|
23 | LISP_COMMENT,
|
---|
24 | LISP_WORD,
|
---|
25 | LISP_WHITESPACE
|
---|
26 | } LISP_PARTS;
|
---|
27 |
|
---|
28 |
|
---|
29 | /////////////////////////////////////////////////////////////////////////////
|
---|
30 | // CLispEditorView
|
---|
31 |
|
---|
32 | IMPLEMENT_DYNCREATE(CLispEditorView, CRichEditView)
|
---|
33 |
|
---|
34 | BEGIN_MESSAGE_MAP(CLispEditorView, CRichEditView)
|
---|
35 | //{{AFX_MSG_MAP(CLispEditorView)
|
---|
36 | ON_WM_DESTROY()
|
---|
37 | ON_WM_CHAR()
|
---|
38 | ON_WM_KEYDOWN()
|
---|
39 | ON_WM_LBUTTONUP()
|
---|
40 | //}}AFX_MSG_MAP
|
---|
41 | // Standard printing commands
|
---|
42 | ON_COMMAND(ID_FILE_PRINT, CRichEditView::OnFilePrint)
|
---|
43 | ON_COMMAND(ID_FILE_PRINT_DIRECT, CRichEditView::OnFilePrint)
|
---|
44 | ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRichEditView::OnFilePrintPreview)
|
---|
45 | END_MESSAGE_MAP()
|
---|
46 |
|
---|
47 |
|
---|
48 | /* ---------------------------------------------------------------------------
|
---|
49 | /////////////////////////////////////////////////////////////////////////////
|
---|
50 | // CLispEditorView construction/destruction
|
---|
51 | ------------------------------------------------------------------------- /**/
|
---|
52 | CLispEditorView::CLispEditorView()
|
---|
53 | {
|
---|
54 | // TODO: add construction code here
|
---|
55 | m_nWordWrap = WrapNone;
|
---|
56 | LastOpenParenIndex = -1;
|
---|
57 | LastCloseParenIndex = -1;
|
---|
58 | }
|
---|
59 |
|
---|
60 | /* ---------------------------------------------------------------------------
|
---|
61 | ------------------------------------------------------------------------- /**/
|
---|
62 | CLispEditorView::~CLispEditorView()
|
---|
63 | {
|
---|
64 | }
|
---|
65 |
|
---|
66 | /* ---------------------------------------------------------------------------
|
---|
67 | ------------------------------------------------------------------------- /**/
|
---|
68 | BOOL CLispEditorView::PreCreateWindow(CREATESTRUCT& cs)
|
---|
69 | {
|
---|
70 | // TODO: Modify the Window class or styles here by modifying
|
---|
71 | // the CREATESTRUCT cs
|
---|
72 |
|
---|
73 | return CRichEditView::PreCreateWindow(cs);
|
---|
74 | }
|
---|
75 |
|
---|
76 | /* ---------------------------------------------------------------------------
|
---|
77 | ------------------------------------------------------------------------- /**/
|
---|
78 | void CLispEditorView::OnInitialUpdate()
|
---|
79 | {
|
---|
80 | CRichEditView::OnInitialUpdate();
|
---|
81 | GetRichEditCtrl().SetBackgroundColor(FALSE, RGB(0, 0, 100));
|
---|
82 | CHARFORMAT cf;
|
---|
83 |
|
---|
84 | GetRichEditCtrl().GetDefaultCharFormat(cf);
|
---|
85 | cf.crTextColor = RGB(255, 255, 255);
|
---|
86 | cf.dwMask = CFM_COLOR | CFM_BOLD | CFM_FACE;
|
---|
87 | cf.dwEffects = 0;
|
---|
88 | strcpy(cf.szFaceName, "Fixedsys");
|
---|
89 | GetRichEditCtrl().SetDefaultCharFormat(cf);
|
---|
90 | GetDocument()->SetModifiedFlag(FALSE);
|
---|
91 |
|
---|
92 | // Set the printing margins (720 twips = 1/2 inch).
|
---|
93 | SetMargins(CRect(720, 720, 720, 720));
|
---|
94 | }
|
---|
95 |
|
---|
96 | /* ---------------------------------------------------------------------------
|
---|
97 | /////////////////////////////////////////////////////////////////////////////
|
---|
98 | // CLispEditorView printing
|
---|
99 | ------------------------------------------------------------------------- /**/
|
---|
100 | BOOL CLispEditorView::OnPreparePrinting(CPrintInfo* pInfo)
|
---|
101 | {
|
---|
102 | // default preparation
|
---|
103 | return DoPreparePrinting(pInfo);
|
---|
104 | }
|
---|
105 |
|
---|
106 | /* ---------------------------------------------------------------------------
|
---|
107 | ------------------------------------------------------------------------- /**/
|
---|
108 | void CLispEditorView::OnDestroy()
|
---|
109 | {
|
---|
110 | // Deactivate the item on destruction; this is important
|
---|
111 | // when a splitter view is being used.
|
---|
112 | CRichEditView::OnDestroy();
|
---|
113 | COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
|
---|
114 | if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
|
---|
115 | {
|
---|
116 | pActiveItem->Deactivate();
|
---|
117 | ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
|
---|
118 | }
|
---|
119 | }
|
---|
120 |
|
---|
121 | #ifdef _DEBUG
|
---|
122 | /* ---------------------------------------------------------------------------
|
---|
123 | /////////////////////////////////////////////////////////////////////////////
|
---|
124 | // CLispEditorView diagnostics
|
---|
125 | ------------------------------------------------------------------------- /**/
|
---|
126 | void CLispEditorView::AssertValid() const
|
---|
127 | {
|
---|
128 | CRichEditView::AssertValid();
|
---|
129 | }
|
---|
130 |
|
---|
131 | /* ---------------------------------------------------------------------------
|
---|
132 | ------------------------------------------------------------------------- /**/
|
---|
133 | void CLispEditorView::Dump(CDumpContext& dc) const
|
---|
134 | {
|
---|
135 | CRichEditView::Dump(dc);
|
---|
136 | }
|
---|
137 |
|
---|
138 | /* ---------------------------------------------------------------------------
|
---|
139 | ------------------------------------------------------------------------- /**/
|
---|
140 | CLispEditorDoc* CLispEditorView::GetDocument() // non-debug version is inline
|
---|
141 | {
|
---|
142 | ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLispEditorDoc)));
|
---|
143 | return (CLispEditorDoc*)m_pDocument;
|
---|
144 | }
|
---|
145 | #endif //_DEBUG
|
---|
146 |
|
---|
147 | /* ---------------------------------------------------------------------------
|
---|
148 | /////////////////////////////////////////////////////////////////////////////
|
---|
149 | // CLispEditorView message handlers
|
---|
150 | ------------------------------------------------------------------------- /**/
|
---|
151 | int IsSeparator(unsigned char c) {
|
---|
152 | if (c == '_')
|
---|
153 | return 0;
|
---|
154 | if (c < '0')
|
---|
155 | return 1;
|
---|
156 | if (c > '9' && c < 'A')
|
---|
157 | return 1;
|
---|
158 | if (c > 'Z' && c < 'a')
|
---|
159 | return 1;
|
---|
160 | if (c > 'z')
|
---|
161 | return 1;
|
---|
162 |
|
---|
163 | return 0;
|
---|
164 |
|
---|
165 | }
|
---|
166 |
|
---|
167 | /* ---------------------------------------------------------------------------
|
---|
168 | ------------------------------------------------------------------------- /**/
|
---|
169 | int WordType(CString Word) {
|
---|
170 | if (((LPCSTR) Word)[0] >= '0' && ((LPCSTR) Word)[0] <= '9')
|
---|
171 | return LISP_NUMBER;
|
---|
172 | if (((LPCSTR) Word)[0] == '"')
|
---|
173 | return LISP_STRING;
|
---|
174 | switch (((LPCSTR) Word)[0]) {
|
---|
175 | case ';':
|
---|
176 | return LISP_COMMENT;
|
---|
177 | break;
|
---|
178 | case '/':
|
---|
179 | if (Word.GetLength() > 1)
|
---|
180 | return LISP_COMMENT;
|
---|
181 | else
|
---|
182 | return LISP_OPERATOR;
|
---|
183 | break;
|
---|
184 |
|
---|
185 | case '=':
|
---|
186 | case '.':
|
---|
187 | case '`':
|
---|
188 | case '-':
|
---|
189 | case '+':
|
---|
190 | case '*':
|
---|
191 | case '<':
|
---|
192 | case '>':
|
---|
193 | return LISP_OPERATOR;
|
---|
194 | break;
|
---|
195 | case ' ':
|
---|
196 | case '\t':
|
---|
197 | case '\n':
|
---|
198 | return LISP_WHITESPACE;
|
---|
199 | }
|
---|
200 | if (IsSeparator(((LPCSTR) Word)[0]))
|
---|
201 | return LISP_SYMBOL;
|
---|
202 | return LISP_WORD;
|
---|
203 | }
|
---|
204 |
|
---|
205 | /* ---------------------------------------------------------------------------
|
---|
206 | ------------------------------------------------------------------------- /**/
|
---|
207 | void CLispEditorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
---|
208 | {
|
---|
209 | // TODO: Add your message handler code here and/or call default
|
---|
210 | CRichEditView::OnChar(nChar, nRepCnt, nFlags);
|
---|
211 | GetRichEditCtrl().HideSelection(TRUE, FALSE);
|
---|
212 | CHARFORMAT cf, cfbak;
|
---|
213 | GetRichEditCtrl().GetDefaultCharFormat(cf);
|
---|
214 | cf.dwMask = CFM_BOLD | CFM_COLOR;
|
---|
215 | cfbak = cf;
|
---|
216 | long Start, End;
|
---|
217 | GetRichEditCtrl().GetSel(Start, End);
|
---|
218 |
|
---|
219 |
|
---|
220 | long First, Last;
|
---|
221 | int Line;
|
---|
222 | Line = GetRichEditCtrl().LineFromChar(Start);
|
---|
223 | First = GetRichEditCtrl().LineIndex(Line);
|
---|
224 | Last = GetRichEditCtrl().LineIndex(Line+1);
|
---|
225 | if (Last == -1)
|
---|
226 | Last = GetRichEditCtrl().GetTextLength();
|
---|
227 | ColorRange(GetRichEditCtrl().LineIndex(Line), GetRichEditCtrl().LineIndex(Line + 1));
|
---|
228 |
|
---|
229 | switch (nChar) {
|
---|
230 | case '\t': {
|
---|
231 | } break;
|
---|
232 | }
|
---|
233 |
|
---|
234 | MatchParen(Start);
|
---|
235 | GetRichEditCtrl().SetSel(Start, End);
|
---|
236 | GetRichEditCtrl().SetSelectionCharFormat(cfbak);
|
---|
237 | GetRichEditCtrl().HideSelection(FALSE, FALSE);
|
---|
238 | }
|
---|
239 |
|
---|
240 | /* ---------------------------------------------------------------------------
|
---|
241 | ------------------------------------------------------------------------- /**/
|
---|
242 | long CLispEditorView::FindNextCloseParen()
|
---|
243 | {
|
---|
244 | long Start;
|
---|
245 | FINDTEXTEX Find;
|
---|
246 | ZeroMemory(&Find, sizeof(Find));
|
---|
247 | CHARRANGE cr;
|
---|
248 | GetRichEditCtrl().GetSel(cr);
|
---|
249 |
|
---|
250 | GetRichEditCtrl().SetSel(cr.cpMin, -1);
|
---|
251 | Start = 0;
|
---|
252 | CString SearchSpace = GetRichEditCtrl().GetSelText();
|
---|
253 | int NumOpen = 0;
|
---|
254 | while (Start < SearchSpace.GetLength() && NumOpen > -1 && Start < 2000) {
|
---|
255 | switch (((LPCSTR) SearchSpace)[Start]) {
|
---|
256 | case '(':
|
---|
257 | if (IsPosCommented(Start + cr.cpMin) == -1 && IsPosQuoted(Start + cr.cpMin) == -1)
|
---|
258 | NumOpen++;
|
---|
259 | break;
|
---|
260 | case ')':
|
---|
261 | if (IsPosCommented(Start + cr.cpMin) == -1 && IsPosQuoted(Start + cr.cpMin) == -1)
|
---|
262 | NumOpen--;
|
---|
263 | break;
|
---|
264 | }
|
---|
265 | Start++;
|
---|
266 | /* long NewStart;
|
---|
267 | NewStart = */
|
---|
268 | }
|
---|
269 |
|
---|
270 | GetRichEditCtrl().SetSel(cr);
|
---|
271 | if (NumOpen > -1)
|
---|
272 | return -1;
|
---|
273 | else
|
---|
274 | return Start + cr.cpMin - 1;
|
---|
275 | }
|
---|
276 |
|
---|
277 | /* ---------------------------------------------------------------------------
|
---|
278 | ------------------------------------------------------------------------- /**/
|
---|
279 | long CLispEditorView::FindPrevOpenParen()
|
---|
280 | {
|
---|
281 | long Start;
|
---|
282 | FINDTEXTEX Find;
|
---|
283 | ZeroMemory(&Find, sizeof(Find));
|
---|
284 | CHARRANGE cr;
|
---|
285 | GetRichEditCtrl().GetSel(cr);
|
---|
286 |
|
---|
287 | Start = cr.cpMin;
|
---|
288 |
|
---|
289 | GetRichEditCtrl().SetSel(0, Start);
|
---|
290 | CString SearchSpace = GetRichEditCtrl().GetSelText();
|
---|
291 | Start--;
|
---|
292 | int NumOpen = 0;
|
---|
293 | while (Start >= 0 && NumOpen < 1 && (cr.cpMin - Start) < 2000) {
|
---|
294 | switch (((LPCSTR) SearchSpace)[Start]) {
|
---|
295 | case '(':
|
---|
296 | if (IsPosCommented(Start) == -1 && IsPosQuoted(Start) == -1)
|
---|
297 | NumOpen++;
|
---|
298 | break;
|
---|
299 | case ')':
|
---|
300 | if (IsPosCommented(Start) == -1 && IsPosQuoted(Start) == -1)
|
---|
301 | NumOpen--;
|
---|
302 | break;
|
---|
303 | }
|
---|
304 | Start--;
|
---|
305 | /* long NewStart;
|
---|
306 | NewStart = */
|
---|
307 | }
|
---|
308 |
|
---|
309 | GetRichEditCtrl().SetSel(cr);
|
---|
310 | // _RPT2(_CRT_WARN, "Found open paren at position %d; NumOpen: %d\n", Start, NumOpen);
|
---|
311 | if (NumOpen < 1)
|
---|
312 | return -1;
|
---|
313 | else
|
---|
314 | return Start + 1;
|
---|
315 | }
|
---|
316 |
|
---|
317 | /* ---------------------------------------------------------------------------
|
---|
318 | ------------------------------------------------------------------------- /**/
|
---|
319 | void CLispEditorView::MatchParen(long Pos)
|
---|
320 | {
|
---|
321 | CHARFORMAT cf;
|
---|
322 | GetRichEditCtrl().GetDefaultCharFormat(cf);
|
---|
323 | cf.dwMask = CFM_BOLD | CFM_COLOR;
|
---|
324 |
|
---|
325 | if (LastOpenParenIndex != -1)
|
---|
326 | FormatWord(LISP_SYMBOL, LastOpenParenIndex, LastOpenParenIndex + 1);
|
---|
327 | if (LastCloseParenIndex != -1)
|
---|
328 | FormatWord(LISP_SYMBOL, LastCloseParenIndex, LastCloseParenIndex + 1);
|
---|
329 |
|
---|
330 | cf.crTextColor = RGB(220, 55, 55);
|
---|
331 | cf.dwEffects = 0;
|
---|
332 |
|
---|
333 | GetRichEditCtrl().SetSel(Pos, Pos);
|
---|
334 | LastOpenParenIndex = FindPrevOpenParen();
|
---|
335 | if (LastOpenParenIndex != -1) {
|
---|
336 | GetRichEditCtrl().SetSel(LastOpenParenIndex, LastOpenParenIndex + 1);
|
---|
337 | GetRichEditCtrl().SetSelectionCharFormat(cf);
|
---|
338 | }
|
---|
339 |
|
---|
340 | GetRichEditCtrl().SetSel(Pos, Pos);
|
---|
341 | LastCloseParenIndex = FindNextCloseParen();
|
---|
342 | if (LastCloseParenIndex != -1) {
|
---|
343 | GetRichEditCtrl().SetSel(LastCloseParenIndex, LastCloseParenIndex + 1);
|
---|
344 | GetRichEditCtrl().SetSelectionCharFormat(cf);
|
---|
345 | }
|
---|
346 | if ((LastOpenParenIndex == -1 || LastCloseParenIndex == -1) && (LastOpenParenIndex != -1 || LastCloseParenIndex != -1))
|
---|
347 | ((CMainFrame*) theApp.m_pMainWnd)->GetStatusBar()->SetPaneText(0, "Detected Mismatched Paren", TRUE);
|
---|
348 | else
|
---|
349 | ((CMainFrame*) theApp.m_pMainWnd)->GetStatusBar()->SetPaneText(0, "Ready", TRUE);
|
---|
350 |
|
---|
351 | }
|
---|
352 |
|
---|
353 | /* ---------------------------------------------------------------------------
|
---|
354 | ------------------------------------------------------------------------- /**/
|
---|
355 | void CLispEditorView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
---|
356 | {
|
---|
357 | // TODO: Add your message handler code here and/or call default
|
---|
358 | CRichEditView::OnKeyDown(nChar, nRepCnt, nFlags); // Call this first so that the caret is updated
|
---|
359 |
|
---|
360 | if (nFlags & 256 && GetRichEditCtrl().GetSelectionType() == SEL_EMPTY) {
|
---|
361 | CPoint Pt = GetRichEditCtrl().GetCaretPos();
|
---|
362 | /* Pt.x = GetRichEditCtrl().LineIndex(-1);
|
---|
363 | Pt.y =
|
---|
364 | */
|
---|
365 | GetRichEditCtrl().HideSelection(TRUE, FALSE);
|
---|
366 | CHARFORMAT cf, cfbak;
|
---|
367 | GetRichEditCtrl().GetDefaultCharFormat(cf);
|
---|
368 | cf.dwMask = CFM_BOLD | CFM_COLOR;
|
---|
369 | cfbak = cf;
|
---|
370 | long Start, End;
|
---|
371 | GetRichEditCtrl().GetSel(Start, End);
|
---|
372 | MatchParen(Start);
|
---|
373 |
|
---|
374 | if (Start <= End)
|
---|
375 | GetRichEditCtrl().SetSel(Start, End);
|
---|
376 | else
|
---|
377 | GetRichEditCtrl().SetSel(End, Start);
|
---|
378 | GetRichEditCtrl().SetSelectionCharFormat(cfbak);
|
---|
379 | GetRichEditCtrl().SetCaretPos(Pt);
|
---|
380 | GetRichEditCtrl().HideSelection(FALSE, FALSE);
|
---|
381 | }
|
---|
382 | }
|
---|
383 |
|
---|
384 | /* ---------------------------------------------------------------------------
|
---|
385 | ------------------------------------------------------------------------- /**/
|
---|
386 | void CLispEditorView::OnLButtonUp(UINT nFlags, CPoint point)
|
---|
387 | {
|
---|
388 | // TODO: Add your message handler code here and/or call default
|
---|
389 | if (GetRichEditCtrl().GetSelectionType() == SEL_EMPTY) {
|
---|
390 | GetRichEditCtrl().HideSelection(TRUE, FALSE);
|
---|
391 | CHARFORMAT cf, cfbak;
|
---|
392 | GetRichEditCtrl().GetDefaultCharFormat(cf);
|
---|
393 | cf.dwMask = CFM_BOLD | CFM_COLOR;
|
---|
394 | cfbak = cf;
|
---|
395 | long Start, End;
|
---|
396 | GetRichEditCtrl().GetSel(Start, End);
|
---|
397 | MatchParen(Start);
|
---|
398 |
|
---|
399 | if (Start <= End)
|
---|
400 | GetRichEditCtrl().SetSel(Start, End);
|
---|
401 | else
|
---|
402 | GetRichEditCtrl().SetSel(End, Start);
|
---|
403 | GetRichEditCtrl().SetSelectionCharFormat(cfbak);
|
---|
404 | GetRichEditCtrl().HideSelection(FALSE, FALSE);
|
---|
405 | }
|
---|
406 | CRichEditView::OnLButtonUp(nFlags, point);
|
---|
407 | }
|
---|
408 |
|
---|
409 | /* ---------------------------------------------------------------------------
|
---|
410 | ------------------------------------------------------------------------- /**/
|
---|
411 | CString CLispEditorView::GetCurrentWord(long &lFirst, long &lLast)
|
---|
412 | {
|
---|
413 | int* buf;
|
---|
414 | int BufLen;
|
---|
415 | CString ret;
|
---|
416 | long Start, End, Line;
|
---|
417 | GetRichEditCtrl().GetSel(Start, End);
|
---|
418 | Line = GetRichEditCtrl().LineFromChar(Start);
|
---|
419 | BufLen = GetRichEditCtrl().LineLength();
|
---|
420 | buf = (int*) malloc(4 + BufLen);
|
---|
421 | ZeroMemory(buf, 4 + BufLen);
|
---|
422 | buf[0] = BufLen;
|
---|
423 | GetRichEditCtrl().GetLine(Line, (LPTSTR) buf, BufLen);
|
---|
424 | CString SearchSpace = (char*) buf;
|
---|
425 | delete buf;
|
---|
426 |
|
---|
427 | int Index, FirstChar, LastChar;
|
---|
428 | Index = Start - GetRichEditCtrl().LineIndex() - 1;
|
---|
429 |
|
---|
430 | int Quote1Pos, Quote2Pos = -1, CommentPos = 0;
|
---|
431 | do {
|
---|
432 | CommentPos = SearchSpace.Find(';', Quote2Pos + 1);
|
---|
433 | if (CommentPos == -1)
|
---|
434 | CommentPos = 16000; // Hopefully this will never be exceeded...
|
---|
435 |
|
---|
436 | Quote1Pos = SearchSpace.Find('"', Quote2Pos + 1);
|
---|
437 | if (Quote1Pos != -1) {
|
---|
438 | Quote2Pos = SearchSpace.Find('"', Quote1Pos + 1);
|
---|
439 | if (Quote2Pos == -1)
|
---|
440 | Quote2Pos = SearchSpace.GetLength();
|
---|
441 | }
|
---|
442 | } while (Quote1Pos != -1 && (Quote1Pos > Index || Quote2Pos < Index) && Quote1Pos < CommentPos);
|
---|
443 |
|
---|
444 | if (Quote1Pos != -1 && Quote1Pos <= Index && Quote2Pos >= Index && Quote1Pos < CommentPos) {
|
---|
445 | ret = SearchSpace.Mid(Quote1Pos, Quote2Pos);
|
---|
446 | lFirst = GetRichEditCtrl().LineIndex() + Quote1Pos;
|
---|
447 | lLast = GetRichEditCtrl().LineIndex() + Quote2Pos + 1;
|
---|
448 | return ret;
|
---|
449 | }
|
---|
450 | else if (CommentPos != 16000) {
|
---|
451 | ret = SearchSpace.Right(SearchSpace.GetLength() - CommentPos);
|
---|
452 | lFirst = GetRichEditCtrl().LineIndex() + CommentPos;
|
---|
453 | lLast = GetRichEditCtrl().LineIndex() + SearchSpace.GetLength() + 1;
|
---|
454 | return ret;
|
---|
455 | }
|
---|
456 |
|
---|
457 | if (IsSeparator(((LPCSTR) SearchSpace)[Index])) {
|
---|
458 | lFirst = Index;
|
---|
459 | lLast = Index + 1;
|
---|
460 | ret = (((LPCSTR) SearchSpace)[Index]);
|
---|
461 | _RPT1(_CRT_WARN, "Current Word is %s\n", (LPCSTR) ret);
|
---|
462 | return ret;
|
---|
463 | }
|
---|
464 | while (Index > 0 && !IsSeparator(((LPCSTR) SearchSpace)[Index]))
|
---|
465 | Index--;
|
---|
466 | if (IsSeparator(((LPCSTR) SearchSpace)[Index]))
|
---|
467 | Index++;
|
---|
468 | FirstChar = Index;
|
---|
469 | Index = Start - GetRichEditCtrl().LineIndex() - 1;
|
---|
470 | while (Index < SearchSpace.GetLength() && !IsSeparator(((LPCSTR) SearchSpace)[Index]))
|
---|
471 | Index++;
|
---|
472 | LastChar = Index;
|
---|
473 |
|
---|
474 | ret = SearchSpace.Right(SearchSpace.GetLength() - FirstChar);
|
---|
475 | ret = ret.Left(LastChar - FirstChar);
|
---|
476 | // _RPT2(_CRT_WARN, "Found open paren at position %d; NumOpen: %d\n", Start, NumOpen);
|
---|
477 | _RPT1(_CRT_WARN, "Current Word is %s\n", (LPCSTR) ret);
|
---|
478 | lFirst = GetRichEditCtrl().LineIndex() + FirstChar;
|
---|
479 | lLast = GetRichEditCtrl().LineIndex() + LastChar;
|
---|
480 | // lLast = LastChar - FirstChar - 1;
|
---|
481 | return ret;
|
---|
482 | }
|
---|
483 |
|
---|
484 | /* ---------------------------------------------------------------------------
|
---|
485 | ------------------------------------------------------------------------- /**/
|
---|
486 | void CLispEditorView::ColorRange(long Start, long End)
|
---|
487 | {
|
---|
488 | CString SearchSpace, CurrentWord, StatusText;
|
---|
489 |
|
---|
490 |
|
---|
491 | int QuotePos, CommentPos;
|
---|
492 | CommentPos = IsPosCommented(Start);
|
---|
493 | if (CommentPos != -1)
|
---|
494 | Start = CommentPos;
|
---|
495 | else {
|
---|
496 | QuotePos = IsPosQuoted(Start);
|
---|
497 | if (QuotePos != -1)
|
---|
498 | Start = QuotePos;
|
---|
499 | }
|
---|
500 |
|
---|
501 | CHARRANGE cr;
|
---|
502 | GetRichEditCtrl().GetSel(cr);
|
---|
503 | GetRichEditCtrl().SetSel(Start, End);
|
---|
504 | SearchSpace = GetRichEditCtrl().GetSelText();
|
---|
505 |
|
---|
506 | int Index = 0, FirstChar = 0;
|
---|
507 | while (FirstChar < SearchSpace.GetLength()) {
|
---|
508 |
|
---|
509 | StatusText.Format("Formatting -- %d%%", (int) ((float) FirstChar / SearchSpace.GetLength() * 100));
|
---|
510 | ((CMainFrame*) theApp.m_pMainWnd)->GetStatusBar()->SetPaneText(0, (LPCSTR) StatusText, TRUE);
|
---|
511 | while (((LPCSTR) SearchSpace)[Index] == ' ')
|
---|
512 | Index++;
|
---|
513 | FirstChar = Index;
|
---|
514 | while (Index < SearchSpace.GetLength() && (!IsSeparator(((LPCSTR) SearchSpace)[Index])))
|
---|
515 | Index++;
|
---|
516 | if (Index == FirstChar) {
|
---|
517 | unsigned char c = ((LPCSTR) SearchSpace)[Index];
|
---|
518 | switch (c) {
|
---|
519 | case ';': {
|
---|
520 | int EndOfLine = SearchSpace.Find('\n', Index);
|
---|
521 | if (EndOfLine == -1)
|
---|
522 | EndOfLine = SearchSpace.GetLength();
|
---|
523 | Index = EndOfLine;
|
---|
524 |
|
---|
525 | } break;
|
---|
526 | case '/': {
|
---|
527 | if (((LPCSTR) SearchSpace)[Index+1] == '*') {
|
---|
528 | int EndComment = SearchSpace.Find("*/", Index + 2);
|
---|
529 | if (EndComment != -1)
|
---|
530 | Index = EndComment + 2;
|
---|
531 | else {
|
---|
532 | Index = SearchSpace.GetLength();
|
---|
533 | }
|
---|
534 | }
|
---|
535 | else
|
---|
536 | Index++;
|
---|
537 | } break;
|
---|
538 | case '"': {
|
---|
539 | int LastQuote = SearchSpace.Find('"', Index + 1);
|
---|
540 | if (LastQuote != -1)
|
---|
541 | Index = LastQuote + 1;
|
---|
542 | else {
|
---|
543 | LastQuote = SearchSpace.Find('\n', Index + 1);
|
---|
544 | if (LastQuote != -1)
|
---|
545 | Index = LastQuote;
|
---|
546 | else
|
---|
547 | Index = SearchSpace.GetLength();
|
---|
548 | }
|
---|
549 |
|
---|
550 | } break;
|
---|
551 | default:
|
---|
552 | Index++;
|
---|
553 | }
|
---|
554 | }
|
---|
555 | CurrentWord = SearchSpace.Mid(FirstChar, Index - FirstChar);
|
---|
556 | // _RPT1(_CRT_WARN, "Current Word is %s\n", (LPCSTR) CurrentWord);
|
---|
557 | FormatWord(WordType(CurrentWord), Start + FirstChar, Start + Index);
|
---|
558 | FirstChar = Index;
|
---|
559 | }
|
---|
560 | GetRichEditCtrl().SetSel(cr);
|
---|
561 | ((CMainFrame*) theApp.m_pMainWnd)->GetStatusBar()->SetPaneText(0, "Ready", TRUE);
|
---|
562 | }
|
---|
563 |
|
---|
564 | /* ---------------------------------------------------------------------------
|
---|
565 | ------------------------------------------------------------------------- /**/
|
---|
566 | /*void *compile(char *&s)
|
---|
567 | {
|
---|
568 | void *ret = NULL;
|
---|
569 | if (!read_ltoken(s, n))
|
---|
570 | lerror(NULL, "unexpected end of program");
|
---|
571 | if (streq(n, "nil"))
|
---|
572 | return NULL;
|
---|
573 | else
|
---|
574 | if (toupper(n[0]) == 'T' && !n[1])
|
---|
575 | return true_symbol;
|
---|
576 | else if (n[0] == '\'') { // short hand for quote function
|
---|
577 | void *cs=new_cons_cell(),*c2=NULL;
|
---|
578 | p_ref r1(cs), r2(c2);
|
---|
579 |
|
---|
580 | ((cons_cell *)cs)->car = (cons_cell*) quote_symbol;
|
---|
581 | c2 = new_cons_cell();
|
---|
582 | ((cons_cell *)c2)->car = (cons_cell*) compile(s);
|
---|
583 | ((cons_cell *)c2)->cdr = NULL;
|
---|
584 | ((cons_cell *)cs)->cdr = (cons_cell*) c2;
|
---|
585 | ret = cs;
|
---|
586 | }
|
---|
587 | else if (n[0] == '`') { // short hand for backquote function
|
---|
588 | void *cs = new_cons_cell(), *c2 = NULL;
|
---|
589 | p_ref r1(cs), r2(c2);
|
---|
590 |
|
---|
591 | ((cons_cell *)cs)->car = (cons_cell*) backquote_symbol;
|
---|
592 | c2 = new_cons_cell();
|
---|
593 | ((cons_cell *)c2)->car = (cons_cell*) compile(s);
|
---|
594 | ((cons_cell *)c2)->cdr = NULL;
|
---|
595 | ((cons_cell *)cs)->cdr = (cons_cell*) c2;
|
---|
596 | ret = cs;
|
---|
597 | }
|
---|
598 | else if (n[0] == ',') { // short hand for comma function
|
---|
599 | void *cs = new_cons_cell(), *c2 = NULL;
|
---|
600 | p_ref r1(cs), r2(c2);
|
---|
601 |
|
---|
602 | ((cons_cell *)cs)->car = (cons_cell*) comma_symbol;
|
---|
603 | c2 = new_cons_cell();
|
---|
604 | ((cons_cell *)c2)->car = (cons_cell*) compile(s);
|
---|
605 | ((cons_cell *)c2)->cdr = NULL;
|
---|
606 | ((cons_cell *)cs)->cdr = (cons_cell*) c2;
|
---|
607 | ret = cs;
|
---|
608 | }
|
---|
609 | else if (n[0] == '(') { // make a list of everything in ()
|
---|
610 | void *first = NULL, *cur = NULL, *last = NULL;
|
---|
611 | p_ref r1(first), r2(cur), r3(last);
|
---|
612 | int done = 0;
|
---|
613 | do {
|
---|
614 | char *tmp = s;
|
---|
615 | if (!read_ltoken(tmp, n)) // check for the end of the list
|
---|
616 | lerror(NULL, "unexpected end of program");
|
---|
617 | if (n[0] == ')') {
|
---|
618 | done = 1;
|
---|
619 | read_ltoken(s, n); // read off the ')'
|
---|
620 | }
|
---|
621 | else {
|
---|
622 | if (n[0] == '.' && !n[1]) {
|
---|
623 | if (!first)
|
---|
624 | lerror(s, "token '.' not allowed here\n");
|
---|
625 | else {
|
---|
626 | read_ltoken(s, n); // skip the '.'
|
---|
627 | ((cons_cell *)last)->cdr = (cons_cell*) compile(s); // link the last cdr to
|
---|
628 | last = NULL;
|
---|
629 | }
|
---|
630 | }
|
---|
631 | else
|
---|
632 | if (!last && first)
|
---|
633 | lerror(s, "illegal end of dotted list\n");
|
---|
634 | else {
|
---|
635 | cur = new_cons_cell();
|
---|
636 | p_ref r1(cur);
|
---|
637 | if (!first)
|
---|
638 | first = cur;
|
---|
639 | ((cons_cell*) cur)->car = (cons_cell*) compile(s);
|
---|
640 | if (last)
|
---|
641 | ((cons_cell *)last)->cdr = (cons_cell*) cur;
|
---|
642 | last = cur;
|
---|
643 | }
|
---|
644 | }
|
---|
645 | }
|
---|
646 | while (!done);
|
---|
647 | ret = comp_optimize(first);
|
---|
648 | }
|
---|
649 | else if (n[0]==')')
|
---|
650 | lerror(s,"mismatched )");
|
---|
651 | else if (isdigit(n[0]) || (n[0]=='-' && isdigit(n[1]))) {
|
---|
652 | lisp_number *num=new_lisp_number(0);
|
---|
653 | sscanf(n,"%d",&num->num);
|
---|
654 | ret=num;
|
---|
655 | }
|
---|
656 | else if (n[0]=='"') {
|
---|
657 | ret=new_lisp_string(str_token_len(s));
|
---|
658 | char *start=lstring_value(ret);
|
---|
659 | for (;*s && (*s!='"' || s[1]=='"');s++,start++) {
|
---|
660 | if (*s=='\\') {
|
---|
661 | s++;
|
---|
662 | if (*s=='n') *start='\n';
|
---|
663 | if (*s=='r') *start='\r';
|
---|
664 | if (*s=='t') *start='\t';
|
---|
665 | if (*s=='\\') *start='\\';
|
---|
666 | }
|
---|
667 | else
|
---|
668 | *start=*s;
|
---|
669 | if (*s=='"')
|
---|
670 | s++;
|
---|
671 | }
|
---|
672 | *start=0;
|
---|
673 | s++;
|
---|
674 | }
|
---|
675 | else if (n[0]=='#') {
|
---|
676 | if (n[1]=='\\') {
|
---|
677 | read_ltoken(s,n); // read character name
|
---|
678 | if (streq(n,"newline"))
|
---|
679 | ret=new_lisp_character('\n');
|
---|
680 | else if (streq(n,"space"))
|
---|
681 | ret=new_lisp_character(' ');
|
---|
682 | else
|
---|
683 | ret=new_lisp_character(n[0]);
|
---|
684 | }
|
---|
685 | else if (n[1]==0) { // short hand for function
|
---|
686 | void *cs=new_cons_cell(),*c2=NULL;
|
---|
687 | p_ref r4(cs),r5(c2);
|
---|
688 | ((cons_cell *)cs)->car = (cons_cell*) make_find_symbol("function");
|
---|
689 | c2=new_cons_cell();
|
---|
690 | ((cons_cell *)c2)->car = (cons_cell*) compile(s);
|
---|
691 | ((cons_cell *)cs)->cdr = (cons_cell*) c2;
|
---|
692 | ret=cs;
|
---|
693 | }
|
---|
694 | else {
|
---|
695 | lbreak("Unknown #\\ notation : %s\n",n);
|
---|
696 | }
|
---|
697 | }
|
---|
698 | else
|
---|
699 | return make_find_symbol(n);
|
---|
700 |
|
---|
701 | return ret;
|
---|
702 | }
|
---|
703 | */
|
---|
704 |
|
---|
705 | /* ---------------------------------------------------------------------------
|
---|
706 | ------------------------------------------------------------------------- /**/
|
---|
707 | void CLispEditorView::FormatWord(int Type, long Start, long End)
|
---|
708 | {
|
---|
709 | CHARFORMAT cf;
|
---|
710 | GetRichEditCtrl().GetDefaultCharFormat(cf);
|
---|
711 | cf.dwMask = CFM_COLOR | CFM_BOLD;
|
---|
712 | cf.dwEffects = 0;
|
---|
713 | switch (Type) {
|
---|
714 | case LISP_SYMBOL:
|
---|
715 | cf.crTextColor = RGB(0, 220, 0);
|
---|
716 | break;
|
---|
717 |
|
---|
718 | case LISP_NUMBER:
|
---|
719 | cf.crTextColor = RGB(0, 255, 255);
|
---|
720 | break;
|
---|
721 |
|
---|
722 | case LISP_STRING:
|
---|
723 | cf.crTextColor = RGB(255, 0, 0);
|
---|
724 | break;
|
---|
725 |
|
---|
726 | case LISP_OPERATOR:
|
---|
727 | cf.crTextColor = RGB(200, 200, 0);
|
---|
728 | break;
|
---|
729 | case LISP_COMMENT:
|
---|
730 | cf.crTextColor = RGB(150, 150, 150);
|
---|
731 | break;
|
---|
732 | case LISP_WHITESPACE:
|
---|
733 | break;
|
---|
734 | default:
|
---|
735 | cf.crTextColor = RGB(255, 255, 255);
|
---|
736 | break;
|
---|
737 |
|
---|
738 | }
|
---|
739 | GetRichEditCtrl().SetSel(Start, End);
|
---|
740 | GetRichEditCtrl().SetSelectionCharFormat(cf);
|
---|
741 | }
|
---|
742 |
|
---|
743 | /* ---------------------------------------------------------------------------
|
---|
744 | Returns the character index of the opening quote if Pos is within a
|
---|
745 | comment; otherwise returns -1
|
---|
746 | ------------------------------------------------------------------------- /**/
|
---|
747 | long CLispEditorView::IsPosCommented(long Pos)
|
---|
748 | {
|
---|
749 | int* buf;
|
---|
750 | int BufLen, Start, Line;
|
---|
751 | CString ret;
|
---|
752 |
|
---|
753 | Line = GetRichEditCtrl().LineFromChar(Pos);
|
---|
754 | BufLen = GetRichEditCtrl().LineLength();
|
---|
755 | Start = GetRichEditCtrl().LineIndex(Line);
|
---|
756 |
|
---|
757 | buf = (int*) malloc(4 + BufLen); ZeroMemory(buf, 4 + BufLen); buf[0] = BufLen;
|
---|
758 | GetRichEditCtrl().GetLine(Line, (LPTSTR) buf, BufLen);
|
---|
759 | CString SearchSpace = (char*) buf;
|
---|
760 | delete buf;
|
---|
761 |
|
---|
762 | int CommentPos = -1;
|
---|
763 | do {
|
---|
764 | CommentPos = SearchSpace.Find(';', CommentPos + 1);
|
---|
765 | if (CommentPos != -1 && (CommentPos + Start < Pos) && IsPosQuoted(CommentPos + Start) == -1)
|
---|
766 | return CommentPos + Start; // We found a commented out section, return the start index
|
---|
767 | } while (CommentPos != -1);
|
---|
768 |
|
---|
769 | FINDTEXTEX ft;
|
---|
770 | ZeroMemory(&ft, sizeof(ft));
|
---|
771 | ft.chrg.cpMax = Pos;
|
---|
772 | int BlockStart, BlockEnd = 0;
|
---|
773 |
|
---|
774 | do {
|
---|
775 | ft.chrg.cpMin = BlockEnd;
|
---|
776 | ft.lpstrText = "/*";
|
---|
777 | BlockStart = GetRichEditCtrl().FindText(0, &ft);
|
---|
778 | if (BlockStart != -1) {
|
---|
779 | ft.chrg.cpMin = BlockStart + 2;
|
---|
780 | ft.lpstrText = "*/";
|
---|
781 | BlockEnd = GetRichEditCtrl().FindText(0, &ft);
|
---|
782 | if (BlockEnd == -1)
|
---|
783 | BlockEnd = Pos + 1;
|
---|
784 | }
|
---|
785 | } while (BlockStart != -1 && BlockEnd < Pos);
|
---|
786 |
|
---|
787 | if (BlockStart != -1 && BlockStart <= Pos && BlockEnd > Pos) {
|
---|
788 | if (IsPosQuoted(BlockStart) == -1)
|
---|
789 | return BlockStart;
|
---|
790 | }
|
---|
791 |
|
---|
792 | return -1;
|
---|
793 | }
|
---|
794 |
|
---|
795 | /* ---------------------------------------------------------------------------
|
---|
796 | Returns the character index of the opening quote if Pos is contained within
|
---|
797 | quotes; otherwise returns -1
|
---|
798 | ------------------------------------------------------------------------- /**/
|
---|
799 | long CLispEditorView::IsPosQuoted(long Pos)
|
---|
800 | {
|
---|
801 | int* buf;
|
---|
802 | int BufLen, Line, Start;
|
---|
803 | CString ret;
|
---|
804 |
|
---|
805 | Line = GetRichEditCtrl().LineFromChar(Pos);
|
---|
806 | BufLen = GetRichEditCtrl().LineLength();
|
---|
807 | Start = GetRichEditCtrl().LineIndex(Line);
|
---|
808 | Pos -= Start;
|
---|
809 | buf = (int*) malloc(4 + BufLen);
|
---|
810 | ZeroMemory(buf, 4 + BufLen);
|
---|
811 | buf[0] = BufLen;
|
---|
812 | GetRichEditCtrl().GetLine(Line, (LPTSTR) buf, BufLen);
|
---|
813 | CString SearchSpace = (char*) buf;
|
---|
814 | delete buf;
|
---|
815 |
|
---|
816 | int Quote1Pos, Quote2Pos = -1;
|
---|
817 | do {
|
---|
818 | Quote1Pos = SearchSpace.Find('"', Quote2Pos + 1);
|
---|
819 | if (Quote1Pos != -1) {
|
---|
820 | Quote2Pos = SearchSpace.Find('"', Quote1Pos + 1);
|
---|
821 | if (Quote2Pos == -1)
|
---|
822 | Quote2Pos = SearchSpace.GetLength();
|
---|
823 | }
|
---|
824 | } while (Quote1Pos != -1 && Quote2Pos < Pos);
|
---|
825 |
|
---|
826 | if (Quote1Pos != -1 && Quote1Pos <= Pos && Quote2Pos > Pos)
|
---|
827 | if (IsPosCommented(Quote1Pos + Start) == -1)
|
---|
828 | return Quote1Pos + Start;
|
---|
829 |
|
---|
830 | return -1;
|
---|
831 | } |
---|