Skip to content

Instantly share code, notes, and snippets.

@Ruin0x11
Last active February 25, 2019 20:46
Show Gist options
  • Save Ruin0x11/323f5a54a6f9a503759937eaa162960d to your computer and use it in GitHub Desktop.
Save Ruin0x11/323f5a54a6f9a503759937eaa162960d to your computer and use it in GitHub Desktop.
Hack for csharp-mode for string interpolation
;; A hack for csharp-mode to highlight string interpolation expressions like $"{foo} {bar}". Adapted from ruby-mode.
(c-lang-defconst c-basic-matchers-after
csharp `(
;; ...
,`(csharp-match-expression-expansion
0 font-lock-variable-name-face t)
))
(defun csharp-match-expression-expansion (limit)
(let* ((prop 'csharp-expansion-match-data)
(pos (next-single-char-property-change (point) prop nil limit))
value)
(when (and pos (> pos (point)))
(goto-char pos)
(or (and (setq value (get-text-property pos prop))
(progn (set-match-data value) t))
(csharp-match-expression-expansion limit)))))
;; verbatim string literals can be multiline
(c-lang-defconst c-multiline-string-start-char
csharp ?@)
(defun csharp-mode-syntax-propertize-function (beg end)
"Apply syntax table properties to special constructs in region BEG to END.
Currently handled:
- Fontify verbatim literal strings correctly
- Highlight text after #region or #pragma as comment"
(save-excursion
(goto-char beg)
(while (search-forward "@\"" end t)
(let ((in-comment-or-string-p (save-excursion
(goto-char (match-beginning 0))
(or (nth 3 (syntax-ppss))
(nth 4 (syntax-ppss))))))
(when (not in-comment-or-string-p)
(let (done)
(while (and (not done) (< (point) end))
(skip-chars-forward "^\"\\\\" end)
(cond
((= (following-char) ?\\)
(put-text-property (point) (1+ (point))
'syntax-table (string-to-syntax "."))
(forward-char 1))
((= (following-char) ?\")
(forward-char 1)
(if (= (following-char) ?\")
(progn
(put-text-property (1- (point)) (1+ (point))
'syntax-table (string-to-syntax "/"))
(forward-char 1))
(setq done t)))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;; begin hack ;;;;;;;;;;;;;;;;;;;;;;;;;;;
(remove-text-properties beg end '(csharp-expansion-match-data))
(goto-char beg)
(while (search-forward "$\"" end t)
(let ((in-comment-or-string-p (save-excursion
(goto-char (match-beginning 0))
(or (nth 3 (syntax-ppss))
(nth 4 (syntax-ppss))))))
(when (not in-comment-or-string-p)
(let (done)
(while (and (not done) (< (point) end))
(when (and (re-search-forward "{[^\"\n}\\\\]*}" end 'move) (or (nth 3 (syntax-ppss)) (nth 4 (syntax-ppss))))
(let ((match-beg (match-beginning 0))
(match-end (match-end 0)))
(when t
(put-text-property match-beg (1+ match-beg) 'csharp-expansion-match-data
(match-data))
(goto-char match-beg)
(while (re-search-forward "[\"`]" match-end 'move)
(put-text-property (match-beginning 0) (match-end 0)
'syntax-table (string-to-syntax ".")))
(goto-char match-end))
))
(skip-chars-forward "^\"\\\\{}" end)
(cond
((= (following-char) ?\\)
(put-text-property (point) (1+ (point))
'syntax-table (string-to-syntax "."))
(forward-char 1)
(if (= (following-char) ?\")
(progn
(put-text-property (1- (point)) (1+ (point))
'syntax-table (string-to-syntax "."))
(forward-char 1))))
((= (following-char) ?\{))
((= (following-char) ?\}))
((= (following-char) ?\")
(forward-char 1)
(if (= (following-char) ?\")
(progn
(put-text-property (1- (point)) (1+ (point))
'syntax-table (string-to-syntax "/"))
(forward-char 1))
(setq done t)))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;; end hack ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(goto-char beg)
(while (re-search-forward "^\\s *#\\s *\\(region\\|pragma\\)\\s " end t)
(when (looking-at "\\s *\\S ")
;; mark the whitespace separating the directive from the comment
;; text as comment starter to allow correct word movement
(put-text-property (1- (point)) (point)
'syntax-table (string-to-syntax "< b"))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment