How to load yasnippets on condition - emacs

I am doing some Drupal programming and have created yasnippets for common functions: db_select, db_delete etc.
I want to load them only when I am working on a Drupal file and not for a common php file. The task is this:
given a list of yasnippet files and the path of the currently opening file
if(path contains '/sites/all/modules')
{
load all the snippets from the list
}
How to do it?

You have two options:
Create a new mode called drupal-mode that inherits everything from php-mode and then define snippets for that mode, check out Derived Modes in the Emacs Manual on how to do that
Add a function to the find-file hook that checks to see if the current buffer is in a particular directory and then load the snippets you want
Either way you'll be doing things based on the current directory or filename.
find-file-hook example
I haven't tested this code but the concept is there. You'll probably have to check the yas/load-directory-1 function to something else or mess around with parameters.
(defun load-drupal-snippets ()
(when (string-match-p "/sites/all/modules" (file-name-directory (buffer-file-name)))
(yas--load-directory-1 "/path/to/drupal/snippets/" 'php-mode 'text-mode)))
(add-hook 'find-file-hook 'load-drupal-snippets)

Related

automatic header for org-mode in emacs

I am using define-auto-insert '("\.org\'" . "org skeleton") macro to insert the header. This is working perfectly fine whenever I'm creating any new org file. But it is also inserting the auto header to the other empty orgs file (created using touch command for some particular reason). Can someone please suggest me any way such that the macro does not add the header in already created empty files when I open them in emacs?
Autoinsert isn't really designed to make this distinction. The simplest way of achieving this is to wrap the auto-insert function with another function and register that with the new file hook instead. For example:
(defun auto-insert-guard ()
"Prevent auto-insertion for files that exist already"
(interactive)
(unless (file-exists-p (buffer-file-name))
(auto-insert)))
Use this for the hook instead:
(add-hook 'find-file-hook 'auto-insert-guard)
It can obviously be more sophisticated than this, where you might only want to have this guard for certain types of file.
Sometimes you see similar things done with defadvice, but this is often more fragile and can be difficult to understand when you come back to it later.

How to use the same file extension for different major-modes

I use a custom version of org-mode called lawlist-org-mode -- every function and variable have the prefix lawlist- and the modified version has many custom features that are not available in the stock version. Occasionally, I like to use the stock org-mode version -- however, that requires manually modifying the auto-mode-alist and then restarting Emacs. This is necessary due to the function and variable org-agenda-files and the check that org-mode performs to verify that the proper major-mode is present. Is there an efficient method to modify this programmatically depending upon the function being called?
The stock org-mode needs this entry:
(add-to-list 'auto-mode-alist '("\\.todo\\'" . org-mode))
The custom version called lawlist-org-mode needs this entry:
(add-to-list 'auto-mode-alist '("\\.todo\\'" . lawlist-org-mode))
Examples:
If I call M-x org-agenda, the .todo files needs to be in org-mode.
If I call M-x lawlist-org-agenda, the .todo file needs to be in lawlist-org-mode.
Some Ideas:  The org-agenda-files are generally accessed by org-agenda functions using the following lines of code -- (org-agenda-files nil 'ifmode) . . . (while (setq file (pop files)). Perhaps modifying the function org-agenda-files would be an option?
The FUNCTION part of an auto-mode-alist entry (i.e., the cdr) is just a function. It is called, in principle to set up a major mode. But it can do anything.
In particular, you could have an entry ("\\.todo\\'" . foo), where function foo conditionally calls either lawlist-org-mode or org-mode.
E.g, it could use lawlist-org-mode when the moon is full and org-mode otherwise. Or it could test a global variable, which you set when you want to switch from one to the other. And so on.
At least that's my reading of the auto-mode-alist doc string. I've never tried it.

irony-mode does not pick up include paths

I've recently started using irony-mode for completion in emacs (24.3.1). However, I seem unable to add additional system include paths to package.
I have this code in my config:
(defun ac-cc-mode-clang-hooks ()
(yas/minor-mode-on)
(auto-complete-mode 1)
;; avoid enabling irony-mode in modes that inherits c-mode, e.g: php-mode
(when (member major-mode irony-known-modes)
(irony-mode 1))
;; set compiler flags to include header files
(setq irony-compile-flags '("-Iinc"))
(irony-reload-flags))
(add-hook 'c++-mode-hook 'ac-cc-mode-clang-hooks)
(add-hook 'c-mode-hook 'ac-cc-mode-clang-hooks)
irony-mode is loaded correctly and completion works perfectly for include paths which the compiler knows explicitly (i.e. everything printed by echo "" | g++ -v -x c++ -E -) but the additional include path inc is not picked up (does not matter whether its a relative or absolute path).
However, if I add the information to the .clang_complete file and load it using C-c C-b the include path is recognised and used. Obviously this is a less than ideal setup because
I don't want to create a .clang_complete file for each single piece of code I'm working on
The .clang_complete file is not loaded automatically.
Is there some working method (which does not involve a per-project setup, I don't want to create project management files for each piece of code) for telling irony-mode where to look for header files?
You can take a look here: https://github.com/Sarcasm/irony-mode#i-got-an-error-due-to-stdargh-how-to-solve-this
The variable irony-libclang-additional-flags should meet your needs.
It should work without calling irony-reload-flags.
It's not a buffer-local variable though, so you don't need to put it in the hook.
I would recommend the following:
(setq irony-libclang-additional-flags
(append '("-I" "inc") irony-libclang-additional-flags))

How do I make an emacs shortcut to switch between related files?

For example, I have the file model/user.py open and I want to have a shortcut that opens controller/user.py. Or I want to switch to test/model/testUser.py (contrived example)
I'd like to make an emacs shortcut which given a file currently open, opens files related in various ways.
If the "related files" follow some kind of pattern, I think it's trivial to write some elisp functions to do the task. Let's say you have a model and need to open his associated controller, you will need to do something like this:
(defun my-open-related-controller ()
(interactive)
(let* ((name (buffer-file-name))) ;gets the filename of the current buffer
;; Of course, this is only an example. The point here is that you need
;; to "discover" the name of the related file based on the current one.
(setf name (replace-regexp-in-string "model" "controller" name))
;; Now you will open the file(if it isn't open already) and switch to it
(find-file name)))
Then you can bind the function to, say, F5:
(define-key name-of-the-mode-map [f5] 'my-open-related-controller)
If you want to crate this binding globally, use:
(global-set-key [f5] 'my-open-related-controller)
Of course, this is just a crude example(since you didn't give many specific details), but should be enough to get you started. Hope it helps!
If you don't fancy writing this yourself and would rather customize an exisiting library, you may like to look at toggle.el. It's designed to do what you're asking for.
There is also the jump.el that rinari uses for this purpose (except for Ruby on Rails projects). I gave the second link, because rinari.el in this project contains settings that manage jumps from one place to another (controller to view, model, migrations, etc.).
It looks like you can get jump.el to jump to a particular method in a file - but that may take a bit of effort.

Emacs c-mode autoloading failed

I want to load my file named "my-c-setup.el" when the c-mode is loading. So, I'm using the function "autoload".
With my python setup, it works well :
lang.el
(autoload 'python-mode "my-python-setup" "" t)
my-python-setup.el
(require 'python)
; ...
I'm trying to do the same with the c-mode, but i does not work :
lang.el
(autoload 'c-mode "my-c-setup" "" t)
my-c-setup.el
(setq c-basic-offset 4)
; ...
When I try to open a file in c-mode (test.c for example), I have the following error :
File mode specification error: (error "Autoloading failed to define function c-mode")
Autoload is not what you're looking for. What it does is simply load some code the first time it is needed, which is a handy way to extend Emacs' functionality while still keeping the start-up time low.
To solve your problem, we gotta think about what you really want to do: do you simply want some of your code to be loaded at some point, or do you want buffer-local customizations for ever buffer that is in c-mode?
If you simply want Emacs to load your code at start-up, either put your code directly into your .emacs file or use load-file or require instead of autoload:
load-file simply takes a file name, loads the lisp code in that file and evaluates it. So if your code is in a file named "/path/to/my-c-setup.el", you could put the following line in your .emacs, and the code will be loaded on every start-up:
(load-file "/path/to/my-c-setup.el")
Perhaps you don't want to give the absolute path name for every file you load. In that case, you could use the function load-library instead which is similar to load-file but tries to find the given filename in any of the directories stored in the variable load-path:
(add-to-list 'load-path "/path/to")
(load-library "my-c-setup.el")
The advantage is that you have to do the add-to-list part only once, and all subsequent calls to load-library will be able to find code in that directory.
An alternative way is the provide/require mechanism: you can make your .el-file "provide" some feature by putting a (provide 'feature) call in it, e.g.
(provide 'my-c-mode-customizations)
Then put an according (require 'feature) in your .emacs file, and your code will be loaded as well:
(require 'my-c-mode-customizations)
However, if you want your code only be loaded when c-mode is activated on a buffer, the way to achieve that is through Emacs' Hook mechanism:
A hook is a variable where you can
store a function or functions to be
called on a particular occasion by an
existing program.
Most major modes provide a customizable hook variable to which you can add functions that will be called whenever the major mode is invoked. For instance, c-mode provides c-mode-hook. In order for your own customizations to be called whenever c-mode is turned on for a buffer, put them in a function, say, my-c-mode-customizations and add the following line to your .emacs file:
(add-hook 'c-mode-hook 'my-c-mode-customizations)
Of course, you still need autoload for Emacs to actually find the definition of that function.
Lisp's autoload does not call a function when a file is loaded but tells lisp that the function is available and that the given file provides it. Whenever someone calls the (not yet defined) function, the file is loaded.
I think that c-mode is already defined and thus fails to re-register.
Autoload doesn't do what you think it does.
http://www.gnu.org/software/emacs/elisp/html_node/Autoload.html
What you probably want are mode-hooks or eval-after-load.
See eval-after-load vs. mode hook for the difference between the two.