1

cc-other-file-alist is part of find-file that looks something like this.

(("\\.cc\\'"
  (".hh" ".h"))
 ("\\.hpp\\'"
  (".cpp"))
 ;; more such entries
)

This is an alist where I'd like to append an additional entry to the cdr of "\\.hpp\\'". I've done it but I feel it's too round about.

(with-eval-after-load 'find-file
  (setq my-cc-other-file-alist (copy-alist cc-other-file-alist))
  ;; create a new cons (key-value) pair in the alist
  (add-to-list 'my-cc-other-file-alist '("\\.mm\\'" (".h")))
  ;; Add: .h -> .mm, .hpp -> .inl
  ;; append to existing value (list) for a given key
  (setcdr (assoc "\\.h\\'" my-cc-other-file-alist)
          (list (append (car (cdr (assoc "\\.h\\'"
                                         my-cc-other-file-alist)))
                        '(".mm"))))
  (setcdr (assoc "\\.hpp\\'" my-cc-other-file-alist)
          (list (append (car (cdr (assoc "\\.hpp\\'"
                                         my-cc-other-file-alist)))
                        '(".inl"))))
  (setq-default ff-other-file-alist 'my-cc-other-file-alist))

I'm sure there would be an elegant way to reference the inner list (cdr) and simply append to it, instead of making copying and replacing. Please tell me there's a better way and show me how!

1

You could use nconc; it appends a structure to the end of a list by setcdring the last cons in the list.

Or you could just prepend a new entry onto the alist, so that it looks like this:

(("\\.hpp\\'"
  (".inl" ".cpp"))
 ("\\.cc\\'"
  (".hh" ".h"))
 ("\\.hpp\\'"
  (".cpp"))
 ;; more such entries
)

This works because everything that reads an alist stops at the first matching entry.

(let ((new-list (cons "\\.inl"
                      (cdr (assoc "\\.hpp\\'"
                                  my-cc-other-file-alist)))))
    (cons (cons "\\.hpp\\'" new-list)
          cc-other-file-alist))

In general it's better to avoid setcdr, nconc, and other functions which modify lists in place, because the list you're modifying might have been shared between multiple data structures. I'm sure it would be fine in this case, though.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.