On Thu, 10 Mar 2005, Stefan Monnier wrote:
>>> You may be right, but I'd like to see your code first, to see how easy and >>> robust it is to use your hook. >> I re-posted my tentative 2002 patch here last night. >Read again: I said "use" not "define". >I.e. I don't want to see the font-lock side of the code, but the awk-mode or >c++-mode side of it. Most importantly, I'd like to see some code that would >solve the problem at hand (see subject) using your new hook. Sorry, I didn't quite understand what you were asking for. I hope the following will do. I can't produce any working c-mode code for this in a hurry. But here is the stuff from cc-awk.el. It has the functionality to fit the hook I'd proposed, but not the same interface. What it does is to expand the region in an AWK buffer to be after-change-font-locked from a physical line to the containing @dfn{logical line}, the maximal sequence of physical lines joined by escaped newlines. It does the Right Thing when a backslash at an EOL gets inserted or deleted. (defun c-awk-beginning-of-logical-line (&optional pos) ;; Go back to the start of the (apparent) current line (or the start of the ;; line containing POS), returning the buffer position of that point. I.e., ;; go back to the last line which doesn't have an escaped EOL before it. ;; ;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any ;; comment, string or regexp. IT MAY WELL BE that this function should not be ;; executed on a narrowed buffer. ;; ;; This function might do hidden buffer changes. (if pos (goto-char pos)) (forward-line 0) (while (and (> (point) (point-min)) (eq (char-before (1- (point))) ?\\)) (forward-line -1)) (point)) (defun c-awk-end-of-logical-line (&optional pos) ;; Go forward to the end of the (apparent) current logical line (or the end of ;; the line containing POS), returning the buffer position of that point. I.e., ;; go to the end of the next line which doesn't have an escaped EOL. ;; ;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any ;; comment, string or regexp. IT MAY WELL BE that this function should not be ;; executed on a narrowed buffer. ;; ;; This function might do hidden buffer changes. (if pos (goto-char pos)) (end-of-line) (while (and (< (point) (point-max)) (eq (char-before) ?\\)) (end-of-line 2)) (point)) (defvar c-awk-old-EOLL 0) (make-variable-buffer-local 'c-awk-old-EOLL) ;; End of logical line following the region which is about to be changed. Set ;; in c-awk-before-change and used in c-awk-after-change. (defun c-awk-before-change (beg end) ;; This function is called exclusively from the before-change-functions hook. ;; It does two things: Finds the end of the (logical) line on which END lies, ;; and clears c-awk-NL-prop text properties from this point onwards. ;; ;; This function might do hidden buffer changes. (save-restriction (save-excursion (setq c-awk-old-EOLL (c-awk-end-of-logical-line end)) (c-save-buffer-state nil (c-awk-clear-NL-props end (point-max)))))) (defun c-awk-end-of-change-region (beg end old-len) ;; Find the end of the region which needs to be font-locked after a change. ;; This is the end of the logical line on which the change happened, either ;; as it was before the change, or as it is now, which ever is later. ;; N.B. point is left undefined. ;; ;; This function might do hidden buffer changes. (max (+ (- c-awk-old-EOLL old-len) (- end beg)) (c-awk-end-of-logical-line end))) ;; ACM 2002/5/25. When font-locking is invoked by a buffer change, the region ;; specified by the font-lock after-change function must be expanded to ;; include ALL of any string or regexp within the region. The simplest way to ;; do this in practice is to use the beginning/end-of-logical-line functions. ;; Don't overlook the possibility of the buffer change being the "recapturing" ;; of a previously escaped newline. (defmacro c-awk-advise-fl-for-awk-region (function) `(defadvice ,function (before get-awk-region activate) ;; When font-locking an AWK Mode buffer, make sure that any string/regexp is ;; completely font-locked. (when (eq major-mode 'awk-mode) (save-excursion (ad-set-arg 1 (c-awk-end-of-change-region (ad-get-arg 0) ; beg (ad-get-arg 1) ; end (ad-get-arg 2))) ; old-len (ad-set-arg 0 (c-awk-beginning-of-logical-line (ad-get-arg 0))))))) (c-awk-advise-fl-for-awk-region font-lock-after-change-function) (c-awk-advise-fl-for-awk-region jit-lock-after-change) (c-awk-advise-fl-for-awk-region lazy-lock-defer-rest-after-change) (c-awk-advise-fl-for-awk-region lazy-lock-defer-line-after-change) >> I think this putting of warning-face on unmatched quotes would be a good >> idea generally. >It would help if you actually explained what you're talking about. >Not everyone uses awk-mode. I'll try; I'm not doing very well at explaining at the moment. Open a new AWK mode buffer with font locking enabled: Start by entering a string: "string At this point, the opening quote has font-lock-warning-face, giving the user a constant niggling reminder to close the string at some point; the remainder of the text has font-lock-string-face. Use escaped NLs to continue the string thus: "string\ on several\ lines. The entire string still has string-face, and the opening quote still has warning-face. Finally, type the closing quote: "string\ on several\ lines." This last action now causes the opening quote to be refonted with string-face. > Stefan -- Alan Mackenzie (Munich, Germany) _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel