diff --git a/lisp/org-src.el b/lisp/org-src.el index baa2b11..3198439 100644 --- a/lisp/org-src.el +++ b/lisp/org-src.el @@ -654,6 +654,43 @@ the language, a switch telling if the content should be in a single line." (org-add-hook 'org-src-mode-hook 'org-src-mode-configure-edit-buffer) +(defun org-src-font-lock-fontify-block (lang start end) + (let* ((lang-mode (org-src-get-lang-mode lang)) + (string (buffer-substring-no-properties start end)) + (modified (buffer-modified-p)) + (fontified-output + (with-temp-buffer + (insert string) + (funcall lang-mode) + (font-lock-fontify-buffer) + (add-text-properties + (point-min) (point-max) + '(font-lock-fontified t fontified t font-lock-multiline t)) + (buffer-substring (point-min) (point-max))))) + (when fontified-output + (goto-char start) + (delete-region start end) + (insert fontified-output) + (set-buffer-modified-p modified))) + t) ;; Tell `org-fontify-meta-lines-and-blocks' that we fontified + +(defun org-src-fontify-block () + "Fontify code block at point" + (interactive) + (let ((org-src-fontify-natively t) + (info (org-edit-src-find-region-and-lang)) + (point (point))) + (font-lock-fontify-region (nth 0 info) (nth 1 info)) + (goto-char point))) + +(defun org-src-get-lang-mode (lang) + "Return major mode that should be used for LANG. +LANG is a string, and the returned major mode is a symbol." + (intern + (concat + ((lambda (l) (if (symbolp l) (symbol-name l) l)) + (or (cdr (assoc lang org-src-lang-modes)) lang)) "-mode"))) + (provide 'org-src) ;; arch-tag: 6a1fc84f-dec7-47be-a416-64be56bea5d8 diff --git a/lisp/org.el b/lisp/org.el index a05f2bf..b381ad0 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -5017,17 +5017,23 @@ will be prompted for." '(display t invisible t intangible t)) t))) +(defvar org-src-fontify-natively nil + "When non-nil, fontify source blocks like their major mode would.") + (defun org-fontify-meta-lines-and-blocks (limit) "Fontify #+ lines and blocks, in the correct ways." (let ((case-fold-search t)) (if (re-search-forward - "^\\([ \t]*#\\+\\(\\([a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)\\(.*\\)\\)" + "^\\([ \t]*#\\+\\(\\([a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)[ \t]*\\(\\([^ \t\n]*\\)[ \t]*\\(.*\\)\\)\\)" limit t) - (let ((beg (match-beginning 0)) - (beg1 (line-beginning-position 2)) - (dc1 (downcase (match-string 2))) - (dc3 (downcase (match-string 3))) - end end1 quoting block-type) + (let* ((beg (match-beginning 0)) + (block-start (match-end 0)) + (block-end nil) + (lang (match-string 7)) + (beg1 (line-beginning-position 2)) + (dc1 (downcase (match-string 2))) + (dc3 (downcase (match-string 3))) + end end1 quoting block-type) (cond ((member dc1 '("html:" "ascii:" "latex:" "docbook:")) ;; a single line of backend-specific content @@ -5047,6 +5053,7 @@ will be prompted for." (concat "^[ \t]*#\\+end" (match-string 4) "\\>.*") nil t) ;; on purpose, we look further than LIMIT (setq end (match-end 0) end1 (1- (match-beginning 0))) + (setq block-end (match-beginning 0)) (when quoting (remove-text-properties beg end '(display t invisible t intangible t))) @@ -5056,6 +5063,8 @@ will be prompted for." (add-text-properties beg beg1 '(face org-meta-line)) (add-text-properties end1 end '(face org-meta-line)) (cond + ((and lang org-src-fontify-natively) + (org-src-font-lock-fontify-block lang block-start block-end)) (quoting (add-text-properties beg1 end1 '(face org-block))) ((not org-fontify-quote-and-verse-blocks))