Set variable value depending on mod - emacs

I'd like to set browse-url-browser-funciton depending on which mod is active for a buffer. This is specifically meant to have pylookup open documentation with w3m and org-mode open links with firefox (when on X11).
At the moment I just have this in my .emacs:
(setq browse-url-browser-function 'w3m-browse-url)

You could set a local value for that variable depending on the major mode, by adding a function to the mode hook. Something like:
(defun use-firefox ()
(set (make-local-variable 'browse-url-browser-function) 'browse-url-firefox))
(add-hook 'org-mode-hook 'use-firefox)
That would use Firefox for links opened in org-mode buffers, and the default value for all other buffers. (Note that it only applies to newly opened buffers.)

Related

Emacs Whitespace Mode ignores whitespace-line-column and fill-column

I have an issue using Emacs 24.1.1 on Mac OS X. I'm editing Jade and CoffeeScript files, so I've turned on whitespace-mode for those file types.
What I'm seeing is that lines longer than 70 characters are highlighted with the whitespace-line font face, regardless of the setting of whitespace-line-column.
In this shot, it is clear that I've customized whitespace-line-column to track fill-column, and I've set fill-column to 120, but much shorter lines are being highlighted.
I've glanced over the code for the Jade mode and don't see anything that would explain the behavior, but I have only a passing understanding of Emacs Lisp.
Thanks in advance for any pointers!
You have to set whitespace-line-column before you activate whitespace-mode. That is, if you want to change its value it does not take effect unless you turn whitespace-mode off and on again. Ironically, that variable is not available for M-x customize until you have activated the mode once :-(
However, you can customize the global value of this variable by putting the following line in your .emacs file:
(setq whitespace-line-column 120)
Since your .emacs is evaluated when you start Emacs, the setting will take effect before you invoke whitespace-mode for the first time and should thus do what you want. If you don't want to set the value globally, but only for Jade files, put the following in your .emacs file instead:
(set (make-local-variable 'whitespace-line-column) 80)
(add-hook 'after-change-major-mode-hook
'(lambda () (when (eq major-mode 'jade-mode)
(setq whitespace-line-column 120))))
If you never want long lines to be highlighted specially at all, there is a third option you might want to consider. You could customize the variable whitespace-style (by typing M-x customize-variable ENTER whitespace-style ENTER) and in the value list remove the entries:
lines
lines-tail
(if any). This should turn off highlighting of long lines globally independent of the value of whitespace-line-column (again, only after you de- and re-activate whitespace mode).

how to disable hl-line feature in specified mode

i enable hl-mode in global scope with the following code.
(global-hl-line-mode t)
to turn off hl-line feature in a specified mode. i do it with the following code.
(add-hook 'org-mode-hook (lambda () (global-hl-line-mode 0)))
but it turns off the hl-line feature for global scope.
how to disable hl-line feature in a specified mode?
There is often information and documentation in the Commentary
section in the source file.
[...]
;; You could make variable `global-hl-line-mode' buffer-local and set
;; it to nil to avoid highlighting specific buffers, when the global
;; mode is used.
[...]
Thus, you can put something like this in your .emacs.
(global-hl-line-mode)
(make-variable-buffer-local 'global-hl-line-mode)
(add-hook 'some-mode-hook (lambda () (setq global-hl-line-mode nil)))
...
use hl-line-mode insted of global-hl-line-mode.
EDIT: You're right. This doesn't work.
The commentary says that the global-mode isn't meant to be used. I take it to
mean that you can't selectively disable it once enabled.
I enable the hl-line-mode in major-mode hooks where I need it.
write the following line in your dotEmacs file, and use f5 to toggle the hl-line-mode
(global-set-key [f5] 'hl-line-mode)

How do I set the Emacs fill-column for a specific mode?

I would like to set the fill-column in Emacs to 120 for Clojure-mode, but leave it at the default (80) otherwise.
How can I do this in my .emacs file?
Thanks.
Add a call to set-fill-column to the clojure-mode-hook.
(add-hook 'clojure-mode-hook
(lambda ()
(set-fill-column 120)))
As fill-column is buffer local, it won't affect other buffers. In fact, you can invoke M-x set-fill-column RET 120 to set the fill column in any Emacs buffer interactively.
You can check if a variable is buffer local by invoking the help: C-h v fill-column specifies:
Automatically becomes buffer-local when set in any fashion.
fill-column is a buffer-local variable, i.e. it can have unique value in each buffer (if you want). So you can just set it in clojure-mode hook.

Set custom keybinding for specific Emacs mode

Though I know how to set a global key-binding in Emacs, I find it hard to even Google out the code for a local (minor-mode specific) key-binding. For instance, I have this code in my .emacs:
;; PDFLaTeX from AucTeX
(global-set-key (kbd "C-c M-p")
(lambda ()
(interactive)
(shell-command (concat "pdflatex " buffer-file-name))))
I don't want to set it globally. Is there a function like local-set-key?
I use the following:
(add-hook 'LaTeX-mode-hook
(lambda () (local-set-key (kbd "C-0") #'run-latexmk)))
to have a bind defined for LaTeX mode alone.
To bind a key in a mode, you need to wait for the mode to be loaded before defining the key. One could require the mode, or use eval-after-load
(eval-after-load 'latex
'(define-key LaTeX-mode-map [(tab)] 'outline-cycle))
Don't forget either '—eval-after-load is not a macro, so it needs them.
You need to identify the key map for that mode (for example, LaTeX-mode-map) and use the function define-key. As an example, along with activating outline-minor-mode within LaTeX mode, I have:
(define-key LaTeX-mode-map [(tab)] 'outline-cycle))
In this case the major mode (LaTeX) holds the key binding, but there is also an outline-minor-mode-map.
None of the other answers satisfied my needs. So this may help other people. I wanted Tab to jump to the beginning of the line if I'm in Evil's normal mode (basically this means everywhere in Emacs), but I instead wanted it to cycle between org item states if I am in an org-mode document.
One option was to mess around with separate bindings and constant binding-rebinding whenever I switched buffers (because evil allows only one binding per key in its normal state).
But a more efficient option was to make Tab run my own code which runs the required function based on which major mode the current buffer uses. So if I am in a org buffer, this code runs org-cycle, and otherwise it runs evil-first-non-blank (go to the first non-whitespace character on the line).
The technique I used here can also be used by calling your custom function via global-set-key instead, for people who use regular non-evil Emacs.
For those who don't know Emacs lisp, the first line after the "if" statement is the true-action, and the line after that is the false-action. So if major-mode equals org-mode, we run org-cycle, otherwise we run evil-first-non-blank in all other modes:
(defun my/tab-jump-or-org-cycle ()
"jumps to beginning of line in all modes except org mode, where it cycles"
(interactive)
(if (equal major-mode 'org-mode)
(org-cycle)
(evil-first-non-blank))
)
(define-key evil-normal-state-map (kbd "<tab>") 'my/tab-jump-or-org-cycle)

How can I set Emacs tab settings by file type?

I need to be able to set the tab settings for the following file types:
.rb: 2 soft spaces
.css, .html.erb: 4 space tabs
I have tried the following, but none of it seems to alter my default tab settings for each of the file types.
;; js-mode-hook has also been tried
(add-hook 'javascript-mode-hook
'(lambda()
(setq tab-width 4)))
(add-hook 'css-mode-hook
'(lambda()
(setq tab-width 4)))
(add-hook 'html-mode-hook
'(lambda()
(setq tab-width 8)))
I am pretty new to emacs so my knowledge of configuration is pretty low.
In emacs each mode has it's own indentation style. The main command to indent (bound to TAB) is indent-for-tab-command.
This command calls mode specific indentation function found in the variable indent-line-function. So each mode has it's own way of doing it.
For Ruby (for my emacs 2 is a default):
(setq ruby-indent-level 2)
For CSS (again, default is 4 for me):
(setq css-indent-offset 4)
Unfortunately SGML mode (on which HTML mode is based) has a very simple indentation mechanism and apparently the level is not configurable.
See the source code of sgml-calculate-indent function.
I personally find it weird. I am not writing HTML, but you can try to modify the sgml-calculate-indent function yourself :). Learn some lisp.
I am using js2 mode, and it indents perfectly by default. For js you have to search for js-indent-level or something similar.
Cheers.
Theres a number of aspects to how Emacs does indentation. Setting the tab-width only specifics how big a tab is if a literal tab is inserted. If you don't wish to use literal tabs for indentation, then you should first disable their insertion (from the manual
):
Emacs normally uses both tabs and
spaces to indent lines. If you prefer,
all indentation can be made from
spaces only. To request this, set
indent-tabs-mode to nil. This is a
per-buffer variable, so altering the
variable affects only the current
buffer, but there is a default value
which you can change as well.which you can change as well.
However, to specify the indentation levels, you'll also need to set the c-basic-offset value variable as well:
(add-hook 'html-mode-hook
'(lambda()
(setq c-basic-offset 4)
(setq indent-tabs-mode nil))
In your case, you may only need the c-basic-offset but try a few combinations and see what works best.
js-mode uses js-indent-level so put (setq js-indent-level 4) into your ~/.emacs (shouldn't have to be in a hook, even, but if you're wondering, it's js-mode-hook, not javascript-mode-hook).
If setting tab-width doesn't change your indentation level for a certain mode, it's often simplest to just open the source for that mode. I found this variable by doing C-h f js-mode, clicking the link "js.el", then searching for "indent", second hit from the top.
However, if you collaborate a lot with other people, it's often better to put a cookie at the top of the file. I typically do // -*- tab-width: 8 -*- in the file, and then I have stuff like this in my ~/.emacs:
(defvaralias 'c-basic-offset 'tab-width)
(defvaralias 'cperl-indent-level 'tab-width)
(defvaralias 'perl-indent-level 'tab-width)
(defvaralias 'js-indent-level 'tab-width)
so that I have less variables to deal with (and don't have to get warnings about the file-local variable being unsafe or whatever if the mode-writer forgot to declare it as safe)
If you are using ELPA's css-mode.el with emacs 23.1.1, you can parametrize the global setting for tab width for CSS files for the tab width by doing the following:
1) Type M-x customize-variable ,
2) Then type css-indent-level,
3) Then after you change the variable to your liking, you do "Save for future sessions".
For HTML and erb: if you are using web-mode (the mode provided by Spacemacs) it can be as simple as:
(setq-default
web-mode-code-indent-offset 2
web-mode-markup-indent-offset 2)
where markup-indent-offset refers to the actual tags and code-indent-offset refers to embedded Ruby in ERB, etc.