Emacs mode question - objective-c

I'm starting to use objective C, and objective C mode works perfectly fine. However, ObjC uses .h files, just like C and C++. I need to be able to use all three. Does anyone know how to get emacs to tell if it should be in objC mode or C/C++ mode?
EDIT: There seems to be some confusion on what I'm asking for. The problem is that I have some .h files that are associated with .m files, and some .h files that are associated with .c files and some that are associated with .cpp files. What I WANT is something that I can stick in my c-mode-common-hook or somewhere that will check to see if it's an objective C .h file, and then force it to objective C-mode, or something. The idea being that then I can just open a .h file and it will automatically be in the correct mode.
Obviously I can manually change mode when I'm in the file, but that's a pain, and I often forget until I hit tab and something wacky happens. This is the solution I'm using now.
I think that the header comment is probably the right way to do this, but in order for it to be TRULY useful, I need to figure out how to get XCode to put the comment in there when It's creating the file for me...
EDIT2:
I'm currently using the header-comment solution. Until I can figure out how to make XCode automatically add the comment, I'm using the following elisp function:
(defun bp-add-objC-comment ()
"Adds the /* -*- mode: objc -*- */ line at the top of the file"
(interactive)
(objc-mode)
(let((p (point)))
(goto-char 0)
(insert "/* -*- mode: objc -*- */\n")
(goto-char (+ p (length "/* -*- mode: objc -*- */\n")))))

You can put a comment like this in the first line of the file:
/* -*- mode: objc -*- */
or
// -*- mode: c++ -*-
as appropriate. More details in Specifying File Variables in the Emacs manual.

Ok, how about a solution that doesn't require putting a special comment in the file?
Check this out:
;; need find-file to do this
(require 'find-file)
;; find-file doesn't grok objc files for some reason, add that
(push ".m" (cadr (assoc "\\.h\\'" cc-other-file-alist)))
(defun my-find-proper-mode ()
(interactive)
;; only run on .h files
(when (string-match "\\.h\\'" (buffer-file-name))
(save-window-excursion
(save-excursion
(let* ((alist (append auto-mode-alist nil)) ;; use whatever auto-mode-alist has
(ff-ignore-include t) ;; operate on buffer name only
(src (ff-other-file-name)) ;; find the src file corresponding to .h
re mode)
;; go through the association list
;; and find the mode associated with the source file
;; that is the mode we want to use for the .h file
(while (and alist
(setq mode (cdar alist))
(setq re (caar alist))
(not (string-match re src)))
(setq alist (cdr alist)))
(when mode (funcall mode)))))))
(add-hook 'find-file-hook 'my-find-proper-mode)
This uses Emacs' built in package to find the corresponding .h/.cc files. So, if the header file you just opened corresponds to a file in c++-mode, the .h file gets put in that mode, if the source is a objc-mode file, the header gets put in that mode.
No special Emacs variables in the comments required.

I would use eproject to help me handle this. Assuming that I don't mix-and-match languages inside a given project, I could just create a .eproject file in the project root that contains the text:
:cc-header-type :objc
Then, I'd set some sort of default mode for .h files:
(add-to-list 'auto-mode-alist '("[.]h$" . c-mode))
Then, add a hook for that mode:
(add-hook 'c-mode-hook (lambda ()
(let ((header-style (eproject-attribute :cc-header-type)))
(when (and header-style
(string-match "[.]h$" (buffer-file-name)))
(case header-style
(:objc (objc-mode))
(:c++ (c++-mode))
(:c (c-mode))))))
Now the mode will be changed automatically according to the setting you make in the .eproject file. (Note that the .eproject file is not the only way to set variables for eproject; if you have a heuristic to detect objective c projects, eproject can get the variable that way also.)
Anyway, if this works for you, let me know so I can add it to the eproject wiki.

Related

Should I define separate module for every file in my Guile project?

Let me explain my problem by comparison. In Common Lisp I could split package definitions to several files, it was enough to declare in each of them that it's in-package and load them.
However in Guile Scheme it looks like I should define-module, separate for each file? Well I still can load some files like in CL and it looks like working, define-modules seems not limited to a single file it is located in like in CL, but I get warnings about undefined names (those that are defined in loaded files), so it gives me feeling that it's not what Guile expects. Is there (1) some way of splitting module across several files like in CL, or (2) should I stick to use-module autoload feature and define-module for each file separatelly?
Indeed in Guile you can load inside a define-module but it will report unbound variable at compile time.
The idiomatic way is the define-module in every file:
;; in earth-software-system.scm
(define-module (earth-software-system))
(use-modules (earth-software-system bullet-train))
(use-modules (srfi srfi-9))
(re-export bullet-train) ;; possibly re-exporting imported bindings
...
Then in earth-software-system/bullet-train.scm you can have:
;; in earth-software-system/bullet-train.scm
(define-module (earth-software-system bullet-train))
(use-modules (srfi srfi-9))
(define-public bullet-train 42)
...
Mind the fact that define-public and a single import per use-modules is not widespread. Here is an example from GNU Guix project that rely on define-module to import and export:
(define-module (guix cpio)
#:use-module ((guix build utils) #:select (dump-port))
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-11)
#:use-module (rnrs bytevectors)
#:use-module (rnrs io ports)
#:use-module (ice-9 match)
#:export (cpio-header?
make-cpio-header
file->cpio-header
file->cpio-header*
write-cpio-header
read-cpio-header
write-cpio-archive))
Also nowadays I prefer the import form which is more easy to the mind that use-modules:
;; in earth-software-system.scm
(define-module (earth-software-system))
(import (prefix (earth-software-system bullet-train) 'bt:)
(import (srfi srfi-9))
(re-export bt:bullet-train) ;; possibly re-exporting imported bindings
...
The prefix syntax is also more easy to the mind than the equivalent using use-modules. This is inspired from R6RS library form and R7RS define-library form. I do not recommend to use library form in Guile since it doesn't report lines correctly.
GNU Guile allow to import forms even if they are not exported using the ## syntax for instance to test some tricky behavior.
You might replace load with include but I never used it in Guile

How do I control into which directory Emacs makes backup files dynamically?

I've seen the post How do I control how Emacs makes backup files? And a few similar post showing very similar solutions. I'm well aware of this approach. But it doesn't do quite what I would like it to do. I would like each file that I'm going to back up have its own personalized backup directory.
For example, let's say I have the following files in the current directory, /Users/me/project_a/
apple.txt
banana.txt
coconut.txt
when I edit these files, I would like them to have their backups stored in directories as follows:
/Users/me/project_a/.backups/apple.txt/
/Users/me/project_a/.backups/banana.txt/
/Users/me/project_a/.backups/coconut.txt/
If I another project directory, say /Users/me/project_b/, with files
needle.doc
thread.doc
thimble.doc
Then, their respective backups should be located as
/Users/me/project_b/.backups/needle.doc/
/Users/me/project_b/.backups/thread.doc/
/Users/me/project_b/.backups/thimble.doc/
Yes, I'm using the name of the file being backed up as part of the path name for the directory into which it's been saved. So, if I have three previous versions of thimble.doc, the full path name for the backups would be:
/Users/me/project_b/.backups/thimble.doc/thimble.doc.~1~
/Users/me/project_b/.backups/thimble.doc/thimble.doc.~2~
/Users/me/project_b/.backups/thimble.doc/thimble.doc.~3~
I have a work around to accomplish that (see below). Ideally, I would name the backups as:
/Users/me/project_b/.backups/thimble.doc/bak.~1~
/Users/me/project_b/.backups/thimble.doc/bak.~2~
/Users/me/project_b/.backups/thimble.doc/bak.~3~
I haven't yet figured out how to get there. (Any suggestions?)
Here's how I'm able to accomplish the less ideal version of this using the .dir-locals.el file with the following code for saving .txt and .tex files.
(let (a b)
(dolist (ae-fh (directory-files-recursively "." "\\.\\(txt\\|tex\\)$"))
(setq a (file-name-nondirectory ae-fh))
(setq a (replace-regexp-in-string "\\." "\\\\." a))
(setq b (concat "./.backups/" (file-name-nondirectory ae-fh)))
(add-to-list 'backup-directory-alist (cons a b))
))
I've already made backup-directory-alist a buffer-local variable.
This accomplishes what I want, but I don't really like this approach. I would like to altogether avoid using .dir-locals.el as a solution to this problem. But also, I would like to avoid junking up the backup-directory-alist. It would be nice if there were a hook I could apply to the backup process which would inform emacs on the fly how it should name the backup file.
Does anyone know how to do this or know where to point me? I've considered trying to redefine make-backup-file-name-function, but I don't entirely understand what I'm doing with the elisp and right now I've got projects that need to be worked on.
What can folks tell me?
I have a partial solution.
It avoids using .dir-locals.el as I want.
It somewhat creates the path on the fly as I want too.
It still uses backup-directory-alist
I add the following to my emacs init file:
(add-hook 'after-change-major-mode-hook
'(lambda ()
(let (a b)
(if (stringp (buffer-file-name))
(progn
(setq a (file-name-nondirectory (buffer-file-name)))
(setq a (replace-regexp-in-string "\\." "\\\\." a))
(setq b (concat "./.backups/" (file-name-nondirectory (buffer-file-name))))
(add-to-list 'backup-directory-alist (cons a b))
)
)
)))
I don't quite know enough about this hook. So, I'm not sure that this will always work. And, I should probably consider whether there might be files for which this convention really is undesirable.
The (stringp (buffer-file-name)) is minimally necessary in the case of buffers for which there is no underlying file: such as *scratch* or even the mini-buffers.
I am still interested in what solutions others might come up with. Ideally, the solution would be more like
/Users/me/project_b/.backups/thimble.doc/bak.~1~
/Users/me/project_b/.backups/thimble.doc/bak.~2~
/Users/me/project_b/.backups/thimble.doc/bak.~3~
than
/Users/me/project_b/.backups/thimble.doc/thimble.doc.~1~
/Users/me/project_b/.backups/thimble.doc/thimble.doc.~2~
/Users/me/project_b/.backups/thimble.doc/thimble.doc.~3~
UPDATE: Persistence will get you places!!!!
I finally did a google search on: "emacs how do i redefine make-backup-file-name". I found this description of an approach which I adapted to my situation. Namely, I did the following:
(defun z:backup:truncate.backup.name (file)
(concat (file-name-directory file) "bak"))
(advice-add 'make-backup-file-name-1 :filter-return #'z:backup:truncate.backup.name)
I'm not entirely sure of what everything is about.
I don't know what the #' syntax does.
I'm not sure what :filter-return does, though I can guess.
I should point out that I still need mae add-hook for 'after-change-major-mode-hook. Without it, I get errors. Apparently, I just can't write the advice function as
(defun z:backup:truncate.backup.name (file)
(concat (file-name-directory file) (file-name-nondirectory) "/bak"))
I tried it and got an error about not being able to back things up. And I think the reason for this is that backup-directory-alist is used to determine the directory path. I've got some ideas for some tweaks here. But this is where things stand currently.
UPDATE: no more need for my add-hook to after-change-major-mode-hook
I've gotten rid of the issue with the backup directory alist not necessarily being set for the correct directory. This is my final form for z:backup:truncate.backup.name
(defun z:backup:truncate.backup.name ()
(let* (
(dir (file-name-directory (buffer-file-name)))
(fh (file-name-nondirectory (buffer-file-name)))
(qdir (concat dir ".backups/" fh))
)
(if (not (file-directory-p qdir))
(progn
(if (file-directory-p dir)
(progn
(make-directory qdir)
))))
(concat qdir "/bak")))
So now more having to tweak backup-directory-alist. I've accomplished everything I wanted. YEAH.

How can i make the spacemacs compilation buffer split horizontally?

I am setting (setq split-width-threshold 100) in my dotspacemacs/user-config, in order to make various buffers split horizontally when the window is wide enough. This works as intended for magit status etc.
However, the compilation log buffer seems to disregard this, and always opens on the bottom.
How can i make the compilation buffer adhere to the split-width-threshold? Alternatively, how can get it to always split horizontally?
I am quite new to both emacs and spacemacs.
The reason for the compilation not to obey your settings is because spacemacs comes with purpose-mode enabled by default. If you use that, then it is a matter of modifying the purpose layouts as you wish. However if you are not using the purpose-mode, then disabling it fixes the issue for me. To just try it out you can do SPC SPC purpose-mode RET and then (with only one window opened) run the compilation.
Here's one way to do it (SPC f e d to get to your config file, then you could put this in the existing dotspacemacs-user-config function) -- here I've shown how to get both grep and compilation buffers popping up on the right:
(require 'dash)
(defun my/popwin-on-right (alist-item)
(let ((props-alist (seq-partition (cdr alist-item) 2)))
(setf (alist-get :position props-alist) '(right))
(setf (alist-get :height props-alist) '(1.0))
(setf (alist-get :width props-alist) '(0.5))
(let ((flattened (apply #'append props-alist)))
(cons (car alist-item) flattened))))
(custom-set-variables
'(popwin:special-display-config
(--map-when (-contains? '("*compilation*" "*grep*") (car it))
(my/popwin-on-right it)
popwin:special-display-config)))
or you could just set popwin:special-display-config more directly, replacing the --map-when call there with a literal list. Just view the variable's existing value e.g. using SPC SPC ielm <RET> to get nice formatting, then cut and paste it in (you'll need to quote the list using '). Or you could do what I do when I want to set a customizable variable as a literal value: use SPC SPC customize, let that update the end of your spacemacs config file with its blob of generated code, then copy out the custom-set-variables it generates into your dotspacemacs-user-config, and delete the blob of code that customize generated).
From another answer
(setq split-height-threshold nil)
(setq split-width-threshold 0)
If you want these settings to only affect compile
(defadvice compile (around split-horizontally activate)
(let ((split-width-threshold 0)
(split-height-threshold nil))
ad-do-it))

Racket/Scribble dynamic pdf generation

Hello all I am trying to dynamically build pdf files based on switches in a global defines file.
In file global_defines.rkt i have
#lang racket/base
(provide (all-defined-out))
(define alpha #f)
(define beta #t)
(define gamma #f)
in file foo.scrbl
#lang scribble/base
#(require "../../pdf_gen/global_defines.rkt")
#title{Getting Started}
#if[(or alpha)
#para{Test text}
""]
#if[(or beta)
(begin
#dynamic-require["bar.scrbl" 'doc]
doc)
""]
and in file bar.scrbl
#lang scribble/base
#(require "../../../pdf_gen/global_defines.rkt")
#(provide (all-defined-out))
#title{BAR}
happy marbles
so with the switches as they are currently i would expect to get something similar to the following out
Getting Started
1.BAR
happy marbles
while there are definitly other ways i can do it i would prefer to stick with scribble as it makes formatting and everything much easier than the other methods i can come up with right now. My main concerns are keeping the switches in one place and being able to pick and choose the content that is triggered by the switches being active, as there is content that will be common between several of the documents but not all of them, and quite a bit of content that only belongs in one or 2 places.
Although this answer isn't as elegant as I'd like, it works.
Basically I think you're talking about conditional compilation. In C you'd use a macro for this. In Racket let's use a macro, too (a macro which is just as brain-dead simple as a C macro).
Also we need a macro because Scribble's include-section is syntax (not a function) and must appear at the top-level. As a result, you can't use it inside of an if or when.
Given that:
define.rkt
#lang racket/base
(provide (all-defined-out))
;; Macros to conditionally include literal text.
;; Each of these should return `text`,
;; or (void) for nothing
(define-syntax-rule (when-alpha text)
text)
(define-syntax-rule (when-beta text)
(void))
;; Macros to conditionally include a .scrbl file
;; Each of these should return include-section,
;; or (void) for nothing
(require scribble/base) ;for include-section
(define-syntax-rule (when-alpha/include mod-path)
(include-section mod-path))
(define-syntax-rule (when-beta/include mod-path)
(void) #;(include-section mod-path))
Currently, this is set to show things for "alpha" but omit them for "beta". Unfortunately there's not a simple #t or #f to toggle. You need to edit the body of each one a bit more than that, as explained in the comments.
manual.scrbl example file conditionally including text and another file
#lang scribble/base
#(require "defines.rkt")
#title{Getting Started}
#when-alpha{#para{Text for alpha}}
#(when-beta/include "includee.scrbl")
includee.scrbl example file being conditionally included
#lang scribble/base
#title{BETA TEXT}
I am text for beta version.
What I don't love about this solution is that you have to create/change a pair of macros for each condition -- one for including literal text, and another for include-section-ing a .scrbl file.

How do I make Org-mode open PDF files in Evince?

In Org-mode when I try to open a link to a PDF file nothing happens. Also, when I do C-c C-e d to export as LaTeX and process to PDF and open the PDF is generated but not opened. How do I make Org-mode open PDF files in Evince?
I am using Org-mode 7.6 in GNU Emacs 23.3.1 and Evince 3.2.1 in Ubuntu 11.10.
M-x customize-variable [RET] org-file-apps [RET]
If org uses your system defaults, you have to edit your ./mailcap file.
Try adding this line:
application/pdf; /usr/bin/evince %s
Another possible construct that could work for this would be to use eval-after-load rather than add-hook. It will only set the values once on startup, you won't have to worry about entries being added or not (unless you regularly reload org).
Combine that with setcdr and you can avoid having to delete from the list and then re-add, add if and you'll ensure that you either add or change the value. The if is only needed for values that aren't in the list by default, just to make sure you don't end up with conflicts somewhere down the line.
(eval-after-load "org"
'(progn
;; .txt files aren't in the list initially, but in case that changes
;; in a future version of org, use if to avoid errors
(if (assoc "\\.txt\\'" org-file-apps)
(setcdr (assoc "\\.txt\\'" org-file-apps) "notepad.exe %s")
(add-to-list 'org-file-apps '("\\.txt\\'" . "notepad.exe %s") t))
;; Change .pdf association directly within the alist
(setcdr (assoc "\\.pdf\\'" org-file-apps) "evince %s")))
Edit for clarification
eval-after-load only evaluates the block when (require 'org) is called. If org is already loaded it will evaluate immediately (I mistakenly thought it ran each time a library was loaded, but it seems to be only the first time). The difference between add-hook and eval-after-load is explained here.
Since org-file-apps is a defcustom it won't change the values if you set them before org is loaded, if you build the list from scratch (including default values as in your second (uglier) solution) you could simply setq in your init.el and everything would work. It also means it won't overwrite your changes.
Adding (if (assoc to the PDF entry won't hurt anything, it will simply ensure that if PDFs are ever removed from the default org-file-apps that it will still be added. The only solution that would not fail if PDFs were removed is your second one. The others all assume the entry exists in one form or another.
You can use a construct similar to https://stackoverflow.com/a/3985552/789593 but adapt it to PDF files and Evince. What you want to do is to alter the list org-file-apps. This can be done by adding the following to your .emacs:
;; PDFs visited in Org-mode are opened in Evince (and not in the default choice) https://stackoverflow.com/a/8836108/789593
(add-hook 'org-mode-hook
'(lambda ()
(delete '("\\.pdf\\'" . default) org-file-apps)
(add-to-list 'org-file-apps '("\\.pdf\\'" . "evince %s"))))
This will delete the default setting for PDF files and instead open them in Evince (and retain everything else included in org-file-apps). I am new to elisp so I do not know if this solution is robust, but it works for me and seems to be more elegant than the one below.
Another option, which seems uglier, is to instead look up the default values and set them all that but change the value for PDF files:
;; PDFs visited in Org-mode are opened in Evince (and other file extensions are handled according to the defaults)
(add-hook 'org-mode-hook
'(lambda ()
(setq org-file-apps
'((auto-mode . emacs)
("\\.mm\\'" . default)
("\\.x?html?\\'" . default)
("\\.pdf\\'" . "evince %s")))))