do not edit — generated by btf.
git.druid.rocksindexdruid520radiumradium-lang-c.el

radium-lang-c.el


;;; radium-lang-c.el, c89, allman/bsd brace style, tabs -*- lexical-binding: t; -*-
 
(require 'cc-mode)
 
(c-add-style "radium-c89"
             '("bsd"
               (c-basic-offset . 8)
               (indent-tabs-mode . t)
               (c-offsets-alist . ((substatement-open . 0)
                                   (statement-cont . 8)
                                   (arglist-intro . 8)
                                   (arglist-close . 0)))))
 
(setq-default c-default-style '((c-mode . "radium-c89")))
 
(add-hook 'c-mode-hook
          (lambda ()
            (setq indent-tabs-mode t
                  tab-width 8
                  c-basic-offset 8
                  ;; cc-mode's own electric reindent (separate from
                  ;; electric-indent-mode, which radium-defaults.el
                  ;; already turns off globally) fires on braces/colons/
                  ;; etc as i type them - same premature-tabs problem,
                  ;; cc-mode-specific switch.
                  c-electric-flag nil)
            (c-set-style "radium-c89")))
 
(add-to-list 'auto-mode-alist '("\\.c\\'" . c-mode))
(add-to-list 'auto-mode-alist '("\\.h\\'" . c-mode))
 
(defun radium-varinit-parse (line)
  "parse a bare c declaration LINE into (type name array-p pointer-p),
or nil when it doesnt look like a plain single-declarator decl: no
\"=\" (already initialized), \"(\" (a call/prototype), \",\" (multiple
declarators - which one would i mean?) or \":\" (a bitfield), and not
a typedef/extern (neither takes an initializer here)."
  (let ((l (string-trim line)) array-p)
    (when (string-match "\\[\\([0-9]*\\)\\]\\s-*\\'" l)
      (setq array-p t l (string-trim (substring l 0 (match-beginning 0)))))
    (unless (or (string-empty-p l)
                (string-match-p "[=(,:]" l)
                (string-match-p "\\`\\(typedef\\|extern\\)\\_>" l))
      (let ((tokens (split-string (replace-regexp-in-string "\\*" " * " l) "[ \t]+" t)))
        (when (>= (length tokens) 2)
          (let* ((name (car (last tokens)))
                 (type-tokens (butlast tokens))
                 (pointer-p (and (member "*" type-tokens) t))
                 (type (mapconcat #'identity type-tokens " ")))
            (when (string-match-p "\\`[A-Za-z_][A-Za-z0-9_]*\\'" name)
              (list type name array-p pointer-p))))))))
 
(defun radium-varinit-default (type array-p pointer-p)
  "the zero-value i want for a c declaration of TYPE: {0} for an array
or a struct/union (c89's own all-fields-zero idiom), NULL for a
pointer, '\\0' for a bare char, 0.0 for float/double, else 0."
  (cond
   (array-p "{0}")
   (pointer-p "NULL")
   ((string-match-p "\\_<char\\_>" type) "'\\0'")
   ((string-match-p "\\_<\\(float\\|double\\)\\_>" type) "0.0")
   ((string-match-p "\\_<\\(struct\\|union\\)\\_>" type) "{0}")
   (t "0")))
 
(defun radium-varinit-trigger ()
  "the instant i finish a bare declaration like `int i;' with its
closing semicolon, rewrite it in place to `int i = 0;' (or whatever
zero-value actually fits the type) - i almost never want an
uninitialized local, and typing the initializer by hand every single
time is the entire reason this exists."
  (when (and (eq last-command-event ?\;)
             (not (minibufferp))
             (not (nth 8 (syntax-ppss))))
    (let* ((eol (point))
           (bol (line-beginning-position))
           (parsed (radium-varinit-parse (buffer-substring-no-properties bol (1- eol)))))
      (when parsed
        (goto-char (1- eol))
        (insert (format " = %s" (radium-varinit-default (nth 0 parsed) (nth 2 parsed) (nth 3 parsed))))))))
 
(add-hook 'c-mode-hook
          (lambda ()
            (add-hook 'post-self-insert-hook #'radium-varinit-trigger nil t)))
 
(provide 'radium-lang-c)
powered by btf.