Org-Mode Babel, switches for code blocks: Can I set defaults? - emacs

In org mode, I can insert source in my org files. There are many header arguments, and I found how to set defaults. So I am down to only switches (here -n -r -l "..")
#+BEGIN_SRC emacs-lisp -n -r -l ";(ref:%s)"
..
#+END_SRC
As I want to use these as site default: How can I set defaults for such switches?
Best in .emacs, but defaults valid for a file/buffer would be of help too.

You can start with this hack
(defadvice org-babel-parse-src-block-match (after org-babel-add-switches activate)
"Add extra-sw to 3th element of the return value"
(let ((extra-sw "-t -w 200"))
(setq v (vconcat ad-return-value))
(aset v 3 (concat (elt v 3) " " extra-sw))
(setq ad-return-value (append v nil))))

Related

Shell (zsh) through Emacs?

I usually run emacs in a terminal to work.
I would like to run a shell inside a emacs window.
I've found the shell command, but I would like to run the zsh I usually
use inside (with my own configuration).
Is it possible?
EDIT : I succeeded to run zsh through Emacs, but the PS1 prompt isn't rendered.
How could I render it? I assume I actually only have the "default" emacs prompt.
Like #TeddyKoker 's link suggested, I did the following :
adding this file as exec-path-from-shell.el to my emacs personnal configuration directories :
;;; exec-path-from-shell.el --- Get environment variables such as $PATH from the shell
;; Copyright (C) 2012-2014 Steve Purcell
;; Author: Steve Purcell <steve#sanityinc.com>
;; Keywords: environment
;; Package-Version: 20141212.846
;; URL: https://github.com/purcell/exec-path-from-shell
;; Version: DEV
;; This file is not part of GNU Emacs.
;; This file is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this file. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; On OS X (and perhaps elsewhere) the $PATH environment variable and
;; `exec-path' used by a windowed Emacs instance will usually be the
;; system-wide default path, rather than that seen in a terminal
;; window.
;; This library allows the user to set Emacs' `exec-path' and $PATH
;; from the shell path, so that `shell-command', `compile' and the
;; like work as expected.
;; It also allows other environment variables to be retrieved from the
;; shell, so that Emacs will see the same values you get in a terminal.
;; If you use a non-POSIX-standard shell like "tcsh" or "fish", your
;; shell will be asked to execute "sh" as a subshell in order to print
;; out the variables in a format which can be reliably parsed. "sh"
;; must be a POSIX-compliant shell in this case.
;; Note that shell variables which have not been exported as
;; environment variables (e.g. using the "export" keyword) may not be
;; visible to `exec-path-from-shell'.
;; Installation:
;; ELPA packages are available on Marmalade and MELPA. Alternatively, place
;; this file on a directory in your `load-path', and explicitly require it.
;; Usage:
;;
;; (require 'exec-path-from-shell) ;; if not using the ELPA package
;; (exec-path-from-shell-initialize)
;;
;; Customize `exec-path-from-shell-variables' to modify the list of
;; variables imported.
;;
;; If you use your Emacs config on other platforms, you can instead
;; make initialization conditional as follows:
;;
;; (when (memq window-system '(mac ns))
;; (exec-path-from-shell-initialize))
;;
;; Alternatively, you can use `exec-path-from-shell-copy-envs' or
;; `exec-path-from-shell-copy-env' directly, e.g.
;;
;; (exec-path-from-shell-copy-env "PYTHONPATH")
;;; Code:
(defgroup exec-path-from-shell nil
"Make Emacs use shell-defined values for $PATH etc."
:prefix "exec-path-from-shell-"
:group 'environment)
(defcustom exec-path-from-shell-variables
'("PATH" "MANPATH")
"List of environment variables which are copied from the shell."
:type '(repeat (string :tag "Environment variable"))
:group 'exec-path-from-shell)
(defvar exec-path-from-shell-debug nil
"Display debug info when non-nil.")
(defun exec-path-from-shell--double-quote (s)
"Double-quote S, escaping any double-quotes already contained in it."
(concat "\"" (replace-regexp-in-string "\"" "\\\\\"" s) "\""))
(defun exec-path-from-shell--tcsh-p (shell)
"Return non-nil if SHELL appears to be tcsh."
(and shell (string-match "tcsh$" shell)))
(defun exec-path-from-shell--login-arg (shell)
"Return the name of the --login arg for SHELL."
(if (exec-path-from-shell--tcsh-p shell) "-d" "-l"))
(defcustom exec-path-from-shell-arguments
(list (exec-path-from-shell--login-arg (getenv "SHELL")) "-i")
"Additional arguments to pass to the shell.
The default value denotes an interactive login shell."
:type '(repeat (string :tag "Shell argument"))
:group 'exec-path-from-shell)
(defun exec-path-from-shell--debug (msg &rest args)
"Print MSG and ARGS like `message', but only if debug output is enabled."
(when exec-path-from-shell-debug
(apply 'message msg args)))
(defun exec-path-from-shell--standard-shell-p (shell)
"Return non-nil iff SHELL supports the standard ${VAR-default} syntax."
(not (string-match "\\(fish\\|tcsh\\)$" shell)))
(defun exec-path-from-shell-printf (str &optional args)
"Return the result of printing STR in the user's shell.
Executes $SHELL as interactive login shell.
STR is inserted literally in a single-quoted argument to printf,
and may therefore contain backslashed escape sequences understood
by printf.
ARGS is an optional list of args which will be inserted by printf
in place of any % placeholders in STR. ARGS are not automatically
shell-escaped, so they may contain $ etc."
(let* ((printf-bin (or (executable-find "printf") "printf"))
(printf-command
(concat printf-bin
" '__RESULT\\000" str "' "
(mapconcat #'exec-path-from-shell--double-quote args " ")))
(shell-args (append exec-path-from-shell-arguments
(list "-c"
(if (exec-path-from-shell--standard-shell-p (getenv "SHELL"))
printf-command
(concat "sh -c " (shell-quote-argument printf-command))))))
(shell (getenv "SHELL")))
(with-temp-buffer
(exec-path-from-shell--debug "Invoking shell %s with args %S" shell shell-args)
(let ((exit-code (apply #'call-process shell nil t nil shell-args)))
(exec-path-from-shell--debug "Shell printed: %S" (buffer-string))
(unless (zerop exit-code)
(error "Non-zero exit code from shell %s invoked with args %S. Output was:\n%S"
shell shell-args (buffer-string))))
(goto-char (point-min))
(if (re-search-forward "__RESULT\0\\(.*\\)" nil t)
(match-string 1)
(error "Expected printf output from shell, but got: %S" (buffer-string))))))
(defun exec-path-from-shell-getenvs (names)
"Get the environment variables with NAMES from the user's shell.
Execute $SHELL according to `exec-path-from-shell-arguments'.
The result is a list of (NAME . VALUE) pairs."
(let* ((dollar-names (mapcar (lambda (n) (format "${%s-}" n)) names))
(values (split-string (exec-path-from-shell-printf
(mapconcat #'identity (make-list (length names) "%s") "\\000")
dollar-names) "\0")))
(let (result)
(while names
(prog1
(push (cons (car names) (car values)) result)
(setq values (cdr values)
names (cdr names))))
result)))
(defun exec-path-from-shell-getenv (name)
"Get the environment variable NAME from the user's shell.
Execute $SHELL as interactive login shell, have it output the
variable of NAME and return this output as string."
(cdr (assoc name (exec-path-from-shell-getenvs (list name)))))
(defun exec-path-from-shell-setenv (name value)
"Set the value of environment var NAME to VALUE.
Additionally, if NAME is \"PATH\" then also set corresponding
variables such as `exec-path'."
(setenv name value)
(when (string-equal "PATH" name)
(setq eshell-path-env value
exec-path (append (parse-colon-path value) (list exec-directory)))))
;;;###autoload
(defun exec-path-from-shell-copy-envs (names)
"Set the environment variables with NAMES from the user's shell.
As a special case, if the variable is $PATH, then `exec-path' and
`eshell-path-env' are also set appropriately. The result is an alist,
as described by `exec-path-from-shell-getenvs'."
(mapc (lambda (pair)
(exec-path-from-shell-setenv (car pair) (cdr pair)))
(exec-path-from-shell-getenvs names)))
;;;###autoload
(defun exec-path-from-shell-copy-env (name)
"Set the environment variable $NAME from the user's shell.
As a special case, if the variable is $PATH, then `exec-path' and
`eshell-path-env' are also set appropriately. Return the value
of the environment variable."
(interactive "sCopy value of which environment variable from shell? ")
(cdar (exec-path-from-shell-copy-envs (list name))))
;;;###autoload
(defun exec-path-from-shell-initialize ()
"Initialize environment from the user's shell.
The values of all the environment variables named in
`exec-path-from-shell-variables' are set from the corresponding
values used in the user's shell."
(interactive)
(exec-path-from-shell-copy-envs exec-path-from-shell-variables))
(provide 'exec-path-from-shell)
;; Local Variables:
;; coding: utf-8
;; indent-tabs-mode: nil
;; mangle-whitespace: t
;; require-final-newline: t
;; checkdoc-minor-mode: t
;; End:
;;; exec-path-from-shell.el ends here
And adding the following in my ~/.emacs :
;; Set terminal :
(setenv "ESHELL" (expand-file-name "~/.emacs_config/scripts/eshell"))
(require 'exec-path-from-shell) ;; if not using the ELPA package
I still don't have access to all zsh features (like prompt expansion) but at least it works better. :)

how to specify multiple file extensions in rgrep?

I tried *.{cc,hh} but it doesn't work (this works for lgrep though). i also tried the method suggested her e http://compgroups.net/comp.emacs/searching-multiple-file-types-with-rgrep/95027 but it seems the interactive mode doesn't allow me to input space. Any idea?
*.cc *.hh is correct. The find command will then use something like:
\( -iname \*.cc -o -iname \*.hh \)
(If you supply a prefix argument, you can view/edit the command before it is executed.)
You can enter the space using quoted-insert: C-qSPC, or just-one-space: M-SPC
I was (in despair) rolling an elisp solution:
(defun mrgrep (pattern extensions dir)
(interactive "ssearch for: \nsextensions (space separated, no *): \nD")
(setq includes (mapconcat (lambda (ext)
(concat (format "--include=\"\\*%s\"" ext)))
(s-split " " extensions)
" "))
(setq cmd (format "grep -ir %s %s %s"
includes
pattern
(concat dir "*")))
(setq cmd (read-from-minibuffer "run grep like this: " cmd))
(compilation-start cmd 'grep-mode)
)
but phils explained how to enter the space !

how to supress popup window from emacs programatically?

For example, I have this setup in my .emacs
(defun gtags-create-or-update ()
"Create or update the gnu global tag file."
(interactive)
(if (y-or-n-p-with-timeout
(format "Run gtags to create/update tag file for code at %s (default no)? "
default-directory)
5 nil) ; default - no run
(unless (= 0 (call-process "global" nil nil nil " -p")) ; tagfile doesn't exist?
(let ((olddir default-directory)
(topdir (read-directory-name
"gtags: top of source tree: " default-directory)))
(cd topdir)
(shell-command "gtags -v")
;; (shell-command "gtags && echo 'created tagfile'")
(cd olddir)) ; restore
;; tagfile already exists; update it
(shell-command "global -uv"))))
;; (shell-command "global -u && echo 'updated tagfile'")))
(add-hook 'c-mode-common-hook
(lambda ()
(require 'gtags)
(gtags-mode t)
(gtags-create-or-update)))
When I run gtags-create-or-update explicitly, emacs prompt in the minibuffer to ask me whether to create/update tag files. However, when I open a c/cpp file, it always pops up a GUI window ask me yes or no, which is super annoying. I am wondering why this is happening.
What #phils says in the comment. To avoid dialog boxes in GUI Emacs, you can set the use-dialog-box to nil Put the line (setq use-dialog-box nil) in your initialization file.

How can I improve this Emacs lisp function?

The intent is to use git grep as the command for M-x grep, and all the buffer benefits that come along with it. Desired functionality:
It reads the word/thing at point as the default value (done, sort of)
It reads the current region as the default argument if a region is set.
The following is the code I have so far:
(defun bw-read-string-at-point ()
(interactive)
(let ((word (word-at-point)))
(set-text-properties 0 (length word) nil word)
word))
(defun bw-git-grep (search-str)
"Uses `git-grep` to find `search-str`"
(interactive
(list
(read-string (format "Search for (%s): " (bw-read-string-at-point)))))
(let ((search-str (if (= (length search-str) 0)
(bw-read-string-at-point) search-str)))
(grep (concat "git --no-pager grep -i -I -nH --no-color --extended-regexp " search-str))))
I feel like the interactive bit there is quite clumsy and could be made much better.
Actually, it looks pretty good. Except you should use the default' argument ofread-string, and the interactive in bw-read-string-at-point should not be there. Or better yet, just use grep-tag-default.
Here's how I'd tweak it:
(defun bw-git-grep (search-str)
"Uses `git-grep` to find `search-str`"
(interactive
(let ((default (grep-tag-default)))
(list
(read-string (format "Search for (default %s): " default)
nil nil default))))
(grep (concat "git --no-pager grep -i -I -nH --no-color --extended-regexp " search-str)))
I would use read-from-minibuffer instead of read-string:
(defun bw-git-grep (pattern)
(interactive
(list
(read-from-minibuffer
"Search for: "
(if (region-active-p)
(buffer-substring-no-properties (region-beginning) (region-end))
(thing-at-point 'word)))))
(let* ((grep-command "git --no-pager grep -i -I -nH --no-color --extended-regexp ")
(command (concat grep-command pattern))
(grep-use-null-device nil))
(grep command)))
Also, you probably need to ensure that grep-use-null-device is nil to avoid grep appending /dev/null to your command (which git doesn't seem to like much)

Update multi-term buffer name based on PWD

If I use konsole or other terminal, the terminal tag name can change based on PWD. But in multi-term, the buffer name is *terminal<number>*. This is not very nice. Because when I switch between them, the name is not very informative. So I want to rename it based on PWD.
I find that the Enter key is bind to term-send-raw, so I write a function
(defadvice term-send-raw (around rename-term-name activate)
(progn
(rename-buffer
(concat "⇒ "
(shell-command-to-string "pwd | xargs basename | tr -d '\n'")
(format-time-string " [%M ∞ %S]")))
ad-do-it))
But the problem is pwd command return the PWD of the terminal buffer, while it is not the PWD of the SHELL in that terminal.
The PWD of the terminal buffer is set by defcustom multi-term-default-dir. And it does not change when the PWD change in the SHELL.
(defcustom multi-term-default-dir "~/"
"The default directory for terms if current directory doesn't exist."
:type 'string
:group 'multi-term)
How can I get the PWD of the SHELL in the terminal?
Regards.
AFAIK there is no easy way to retrieve information from a running process.
But if you want to get the current directory you could:
ask the shell to print it
parse and trace the command-line for functions like cd, pushd, popd…
poll /proc/PID/cwd
The first method is described in the header of term.el (M-xfind-libraryRETtermRET).
And now, thank you for your question, you gave me the opportunity to do this:
(defadvice term-send-input (after update-current-directory)
(let* ((pid (process-id (get-buffer-process (current-buffer))))
(cwd (file-truename (format "/proc/%d/cwd" pid))))
(cd cwd)))
(ad-activate 'term-send-input)
It's a naive implementation of the third method and it doesn't work if the user uses su or ssh. However, I don't know if it's possible withouth using the first or the second method.
In your case, you can just replace the cd command with whatever you want.
Building off of Daimrod's answer for polling /proc/PID/cwd, I found a way get around the problem that Reed pointed out where the advice doesn't pick up the updated CWD immediately and you have to hit Enter twice.
If you move the CWD update code to its own function and use run-at-time to call it from the advice at a later time, it will pick up the updated CWD correctly. Unfortunately I don't know enough about Emacs' scheduling to explain why this works (any enlightenment would be appreciated).
Here's my code based on Daimrod's. Note I advised term-send-input for line-mode and term-send-return for char-mode. I tested this using multi-term on Emacs 24.3.1:
(defadvice term-send-input (after update-current-directory)
(run-at-time "0.1 sec" nil 'term-update-dir)
)
(ad-activate 'term-send-input)
(defadvice term-send-return (after update-current-directory)
(run-at-time "0.1 sec" nil 'term-update-dir)
)
(ad-activate 'term-send-return)
(defun term-update-dir ()
(let* ((pid (process-id (get-buffer-process (current-buffer))))
(cwd (file-truename (format "/proc/%d/cwd" pid))))
(unless (equal (file-name-as-directory cwd) default-directory)
(message (concat "Switching dir to " cwd))
(cd cwd)))
)
Most terminals get their window name from the command echo -en. In zsh you can put this in your ~/.zshenv
precmd() { echo -en "\e]0;`basename ${PWD}`\a" }
and that will get the basename of your PWD environment variable. Ideally multi-term would do something similar and put it in multi-term-buffer-name, which is the variable which holds its buffer name.
Yes, this is not a complete solution. I'm hoping for one too!
Try this:
(defun open-or-jump-to-multi-term ()
(interactive)
(if (string-prefix-p "*terminal<" (buffer-name))
(delete-window)
(progn
(setq bufname (concat "*terminal<" (directory-file-name (file-name-directory (buffer-file-name))) ">"))
(if (get-buffer-process bufname)
(switch-to-buffer-other-window bufname)
(progn
(split-window-right)
(other-window 1)
(multi-term)
(rename-buffer bufname)
)
)))
)
(global-set-key (kbd "C-`") 'open-or-jump-to-multi-term)