<commit_before>(defpackage :lem-c-mode
  (:use :cl :lem)
  (:import-from
   :lem.language-mode
   :language-mode
   :indent
   :beginning-of-defun-function
   :end-of-defun-function)
  (:export :*c-mode-hook*))
(in-package :lem-c-mode)

(defvar *c-mode-hook* '())

(defvar *c-syntax-table*
  (let ((table (make-syntax-table
                :space-chars '(#\space #\tab #\newline)
                :symbol-chars '(#\_)
                :paren-alist '((#\( . #\))
                               (#\{ . #\})
                               (#\[ . #\]))
                :string-quote-chars '(#\" #\' #\`)
                :expr-prefix-chars '(#\, #\;)
                :expr-suffix-chars '(#\,)
                :line-comment-string "//"
                :block-comment-pairs '(("/*" . "*/"))))
        (tmlanguage (lem-c-mode.grammer:make-tmlanguage-c)))
    (set-syntax-parser table tmlanguage)
    table))

(define-major-mode c-mode language-mode
    (:name "c"
     :keymap *c-mode-keymap*
     :syntax-table *c-syntax-table*)
  (setf (variable-value 'enable-syntax-highlight) t)
  (setf (variable-value 'calc-indent-function) 'calc-indent)
  (setf (variable-value 'indent-tabs-mode) t)
  (setf (variable-value 'beginning-of-defun-function) 'c-beginning-of-defun)
  (setf (variable-value 'end-of-defun-function) 'c-end-of-defun)
  (run-hooks *c-mode-hook*))

(define-key *c-mode-keymap* "}" 'c-electric-brace)

(define-command c-electric-brace () ()
  (insert-character (current-point) #\})
  (indent))

(defun move-to-match-line (point n regex)
  (let ((step (if (plusp n) 1 -1)))
    (dotimes (_ (abs n))
      (when (start-line-p point)
        (unless (line-offset point step)
          (return-from move-to-match-line)))
      (loop
        (when (ppcre:scan regex (line-string point))
          (return))
        (unless (line-offset point step)
          (return-from move-to-match-line))))))

(defun c-beginning-of-defun (point n)
  (move-to-match-line point (- n) (ppcre:create-scanner "^\\w[^=(]*")))

(defun c-end-of-defun (point n)
  (if (minusp n)
      (c-beginning-of-defun point (- n))
      (search-forward-regexp point "^\\}")))

(defvar *indent-line-function* nil)

(defun %indent (p indent)
  (when *indent-line-function*
    (funcall *indent-line-function* p indent)))

(defun delimiter-line-p (p)
  (multiple-value-bind (start)
      (ppcre:scan "[^\\\\]?;\\s*(?:/\\*.*?\\*/|//.*?)?\\s*$" (line-string p))
    (when start
      (with-point ((p p))
        (line-offset p 0 (1+ start))
        (not (in-string-or-comment-p p))))))

(defun end-block-line-p (p)
  (with-point ((p p))
    (loop :for start := 0 :then (1+ i)
          :for i := (position #\} (line-string p) :start start)
          :while i
          :do (unless (let ((p (character-offset (line-start p) i)))
                        (check-type p point)
                        (in-string-or-comment-p p))
                (return i)))))

(defun dangling-start-p (p)
  (let ((str (looking-at p "do|else\\s+if|else|for|if|switch|while")))
    (character-offset p (length str))
    (or (not (eql #\( (character-at p)))
        (form-offset p 1))
    (let ((old-linenumber (line-number-at-point p)))
      (skip-space-and-comment-forward p)
      (/= old-linenumber (line-number-at-point p)))))

(defun unbalanced-p (state)
  (if (member #\( (pps-state-paren-stack state)) t nil))

(defun unbalanced-indent (p indent start)
  (flet ((jmp-start-paren (p)
           (loop
             (scan-lists p -1 1)
             (when (eql #\( (character-at p))
               (return)))))
    (let ((state))
      (%indent p indent)
      (jmp-start-paren p)<commit_msg>c-modeの字下げを修正<commit_after>(defpackage :lem-c-mode
  (:use :cl :lem)
  (:import-from
   :lem.language-mode
   :language-mode
   :indent
   :beginning-of-defun-function
   :end-of-defun-function)
  (:export :*c-mode-hook*))
(in-package :lem-c-mode)

(defvar *c-mode-hook* '())

(defvar *c-syntax-table*
  (let ((table (make-syntax-table
                :space-chars '(#\space #\tab #\newline)
                :symbol-chars '(#\_)
                :paren-alist '((#\( . #\))
                               (#\{ . #\})
                               (#\[ . #\]))
                :string-quote-chars '(#\" #\' #\`)
                :expr-prefix-chars '(#\, #\;)
                :expr-suffix-chars '(#\,)
                :line-comment-string "//"
                :block-comment-pairs '(("/*" . "*/"))))
        (tmlanguage (lem-c-mode.grammer:make-tmlanguage-c)))
    (set-syntax-parser table tmlanguage)
    table))

(define-major-mode c-mode language-mode
    (:name "c"
     :keymap *c-mode-keymap*
     :syntax-table *c-syntax-table*)
  (setf (variable-value 'enable-syntax-highlight) t)
  (setf (variable-value 'calc-indent-function) 'calc-indent)
  (setf (variable-value 'indent-tabs-mode) t)
  (setf (variable-value 'beginning-of-defun-function) 'c-beginning-of-defun)
  (setf (variable-value 'end-of-defun-function) 'c-end-of-defun)
  (run-hooks *c-mode-hook*))

(define-key *c-mode-keymap* "}" 'c-electric-brace)

(define-command c-electric-brace () ()
  (insert-character (current-point) #\})
  (indent))

(defun move-to-match-line (point n regex)
  (let ((step (if (plusp n) 1 -1)))
    (dotimes (_ (abs n))
      (when (start-line-p point)
        (unless (line-offset point step)
          (return-from move-to-match-line)))
      (loop
        (when (ppcre:scan regex (line-string point))
          (return))
        (unless (line-offset point step)
          (return-from move-to-match-line))))))

(defun c-beginning-of-defun (point n)
  (move-to-match-line point (- n) (ppcre:create-scanner "^\\w[^=(]*")))

(defun c-end-of-defun (point n)
  (if (minusp n)
      (c-beginning-of-defun point (- n))
      (search-forward-regexp point "^\\}")))

(defvar *indent-line-function* nil)

(defun %indent (p indent)
  (when *indent-line-function*
    (funcall *indent-line-function* p indent)))

(defun delimiter-line-p (p)
  (multiple-value-bind (start)
      (ppcre:scan "[^\\\\]?;\\s*(?:/\\*.*?\\*/|//.*?)?\\s*$" (line-string p))
    (when start
      (with-point ((p p))
        (line-offset p 0 (1+ start))
        (not (in-string-or-comment-p p))))))

(defun end-block-line-p (p)
  (with-point ((p p))
    (loop :for start := 0 :then (1+ i)
          :for i := (position #\} (line-string p) :start start)
          :while i
          :do (unless (let ((p (character-offset (line-start p) i)))
                        (check-type p point)
                        (in-string-or-comment-p p))
                (return i)))))

(defun dangling-start-p (p)
  (let ((str (looking-at p "(?:do|else\\s+if|else|for|if|switch|while)\\s*")))
    (character-offset p (length str))
    (or (not (eql #\( (character-at p)))
        (form-offset p 1))
    (let ((old-linenumber (line-number-at-point p)))
      (skip-space-and-comment-forward p)
      (/= old-linenumber (line-number-at-point p)))))

(defun unbalanced-p (state)
  (if (member #\( (pps-state-paren-stack state)) t nil))

(defun unbalanced-indent (p indent start)
  (flet ((jmp-start-paren (p)
           (loop
             (scan-lists p -1 1)
             (when (eql #\( (character-at p))
               (return)))))
    (let ((state))
      (%indent p indent)
      (jmp-start-paren p)
{'fraction_non_alphanumeric': 0.20208963431399504, 'fraction_numerical': 0.002474566950783613, 'mean_word_length': 2.1575520833333335, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7211315', 'n_tokens_mistral': 2758, 'n_tokens_neox': 2660, 'n_words': 541}