Discussion on a few elisp functions, like shell-command, start-process - emacs

(shell-command ...)
(async-shell-command)
(call-process ...)
(start-process ...)
What are the major difference and context to use them? It would be great if there's any summary? Bow//

in short:
| synchronous | asynchronous
-------------------+--------------------------+-------------------------+
interactive | shell-command | async-shell-command
programmatically | call-process | start-process
interactive: from the editing environment
programmatically: from elisp
synchronous: start and wait till done
asynchronous: start and return immediately while it is running in the background.
For more details : C-h f name-of-function

Related

setting the emacs theme on startup without the interactive mode

I am using the following snippet to set the theme on Emacs startup.
(load-theme 'sanityinc-tomorrow-eighties)
However it also asks me for confirmation that this will load some lisp code, how do I turn off this confirmation?
Use load-theme with a non-nil NOCONFIRM arg.
C-h f load-theme tells you that (load-theme 'sanityinc-tomorrow-eighties t) should load the theme without asking for confirmation:
,----
| load-theme is an interactive compiled Lisp function in `custom.el'.
|
| (load-theme THEME &optional NO-CONFIRM NO-ENABLE)
|
| Load Custom theme named THEME from its file.
| The theme file is named THEME-theme.el, in one of the directories
| specified by `custom-theme-load-path'.
|
| If the theme is not considered safe by `custom-safe-themes',
| prompt the user for confirmation before loading it. But if
| optional arg NO-CONFIRM is non-nil, load the theme without
| prompting.
|
| Normally, this function also enables THEME. If optional arg
| NO-ENABLE is non-nil, load the theme but don't enable it, unless
| the theme was already enabled.
|
| This function is normally called through Customize when setting
| `custom-enabled-themes'. If used directly in your init file, it
| should be called with a non-nil NO-CONFIRM argument, or after
| `custom-safe-themes' has been loaded.
|
| Return t if THEME was successfully loaded, nil otherwise.
`----
You should learn to ask Emacs first. C-h f is the least you should know and use, before asking something so simple here.

Emacs rearrange split panes

If I'm working in (terminal) Emacs and have 2 buffers on screen using a horizontal split:
+--------------------------+
| |
| |
| |
| |
+--------------------------+
| |
| |
| |
| |
+--------------------------+
Then I decide to open the slime repl, Emacs will split one of those horizontal panes vertically:
+--------------------------+
| |
| |
| |
| |
+-------------+------------+
| | |
| | slime |
| | |
| | |
+-------------+------------+
But what I want is to have slime on the right, using the full height of the window:
+-------------+------------+
| | |
| | |
| | |
| | |
+-------------+ slime |
| | |
| | |
| | |
| | |
+-------------+------------+
Is there any easy way to get from the arrangement Emacs automatically gave me, to the one I want (e.g. a rotate arrangement), or do I explicitly close and re-split the windows myself?
EDIT | Also curious if I can directly open a full vertical split if I'm currently using a full horizontal split, or if it's effectively impossible.
If you like pre-set window configurations, take a look at the "workspace management" pakages:
Perspective gives you named workspaces
Equilibrium Emacs Window Manager is similar but more sophisticated tool which allows to configure popup placement, window configuraion, buffers, fonts and keybindings.
There is more on the project management page on EmacsWiki.
To your second question, here is what I have in my configuration to flip horizontal/vertical splits (credit: https://github.com/yyr/emacs.d):
(defun split-window-func-with-other-buffer (split-function)
(lexical-let ((s-f split-function))
(lambda ()
(interactive)
(funcall s-f)
(set-window-buffer (next-window) (other-buffer)))))
(defun split-window-horizontally-instead ()
(interactive)
(save-excursion
(delete-other-windows)
(funcall (split-window-func-with-other-buffer 'split-window-horizontally))))
(defun split-window-vertically-instead ()
(interactive)
(save-excursion
(delete-other-windows)
(funcall (split-window-func-with-other-buffer 'split-window-vertically))))
(global-set-key "\C-x|" 'split-window-horizontally-instead)
(global-set-key "\C-x_" 'split-window-vertically-instead)
There are certainly libraries for transforming a frame's window configuration (flip, rotate, etc...), and other libraries for rotating the visible buffers through the available windows. Combining those would achieve your aim.
I like TransposeFrame for the former, and I can see at least a couple of options for the latter:
https://github.com/banister/window-rotate-for-emacs
http://www.emacswiki.org/emacs/TransposeWindows
In general, CategoryWindows on the Wiki should be useful to you.
Note that the window configuration transforms do need to delete and re-create the splits, so the original window objects do not all survive the process. In that respect, it's not actually possible to do what you're asking; but for most purposes, 'faking it' is sufficient.
Here's a function that does what you want. After loading it into emacs, select the buffer you want to rearrange and do an M-x my-shift-window-right. You can also bind it to a key with global-set-key.
(defun my-shift-window-right (&optional start-window)
"Reset the current window configuration with START-WINDOW
on the right and the rest of the windows on the left. START-WINDOW defaults to
the selected window. Return START-WINDOW, or nil if START-WINDOW isn't live or
if there is only one visible window."
(interactive (list (selected-window)))
(if (or (one-window-p)
(and start-window
(not (window-live-p start-window)))) nil
(let ((other-buffers '())
(start-window (or start-window (selected-window))))
;; add all visible buffers other than the current one to other-buffers list
(walk-windows #'(lambda (window)
(when (not (eq window start-window))
(add-to-list 'other-buffers (window-buffer window)))))
(delete-other-windows)
;; pop the first "other buffer" into a split window on the left
(set-window-buffer (select-window (split-window start-window nil 'left))
(pop other-buffers))
;; make a split window for each buffer in the "other-buffers" list
;; select the start-window and return it when finished
(dolist (buffer other-buffers (select-window start-window))
(set-window-buffer (split-window (selected-window) nil 'above) buffer)))))
This function cycles through the other visible windows and stores each of their buffers in a list called other-buffers. Then it rearranges the windows the way you described by iterating over the other-buffers list.

How do I make this Emacs frame keep its buffer and not get resized?

My Emacs frame looks like this:
+---------------------------+
| | |
| | |
| | B |
| A | |
| | |
| | |
| |-------------|
| | C |
+---------------------------+
C is usually a terminal with some kind of long-running process, like a web server or daemon. Unfortunately, all sorts of things like to switch the buffer in that window and occasionally it gets resized. How can I lock the buffer and height of window C?
If you don't want to be annoyed by window stealing and resizing, put the following lines in your .emacs for a definitive solution that works even with libraries like gud that tries to open a new frame when they can't steal your windows :
(see this answer for info on the following advice)
(defadvice pop-to-buffer (before cancel-other-window first)
(ad-set-arg 1 nil))
(ad-activate 'pop-to-buffer)
;; Toggle window dedication
(defun toggle-window-dedicated ()
"Toggle whether the current active window is dedicated or not"
(interactive)
(message
(if (let (window (get-buffer-window (current-buffer)))
(set-window-dedicated-p window
(not (window-dedicated-p window))))
"Window '%s' is dedicated"
"Window '%s' is normal")
(current-buffer)))
;; Press [pause] key in each window you want to "freeze"
(global-set-key [pause] 'toggle-window-dedicated)
and customize pop-up-windows variable to nil.
you could also use StickyWindows instead of window-dedicated feature.
One possibility is to dedicate the window to its buffer, using set-window-dedicated-p. This will not prevent the window from being resized manually, only protect it from being clobbered by display-buffer. For example,
(add-hook 'shell-mode-hook
(lambda ()
(interactive)
(set-window-dedicated-p (selected-window) 1)))
Replace shell-mode-hook as necessary.
This one also works fine (for emacs 24) https://lists.gnu.org/archive/html/help-gnu-emacs/2007-05/msg00975.html
(define-minor-mode sticky-buffer-mode
"Make the current window always display this buffer."
nil " sticky" nil
(set-window-dedicated-p (selected-window) sticky-buffer-mode))
You could use winner-mode to be able to undo the changes to be the window sizes.
You could also explicitly save and restore the window configuration in registers.

How do I make Emacs' other-window command ignore terminal windows?

Emacs does an okay job of being a window manager. I've been splitting up my Emacs frame like this:
+---------------------------+
| | |
| | |
| | B |
| A | |
| | |
| | |
| |-------------|
| | C |
+---------------------------+
C is usually a terminal with some kind of long-running process, like a web server or daemon. Occasionally I'll move the point there to restart the daemon, but most of the time I'd like to swap only between A and B. How can I make this convenient?
There's nothing built-in to do what you want. You can use the following code to do what you want (just customize the regular expression to match the name of the buffer(s) you want to avoid).
Note: the my-other-window doesn't implement all the features other-window does, that is left as an exercise for the reader.
my-other-window will try to switch to a window whose buffer doesn't match the avoid-window-regexp. If there's no such window available, then it just switches to the next one.
(require 'cl)
(defvar avoid-window-regexp "^[0-9]$")
(defun my-other-window ()
"Similar to 'other-window, only try to avoid windows whose buffers match avoid-window-regexp"
(interactive)
(let* ((window-list (delq (selected-window) (window-list)))
(filtered-window-list (remove-if
(lambda (w)
(string-match-p avoid-window-regexp (buffer-name (window-buffer w))))
window-list)))
(if filtered-window-list
(select-window (car filtered-window-list))
(and window-list
(select-window (car window-list))))))
And bind it appropriately:
(global-set-key (kbd "C-x o") 'my-other-window)
This works for eshell:
(add-hook 'eshell-mode-hook (lambda ()
(set-window-parameter (first (window-list)) 'no-other-window t)))
Setting no-other-window to non-nil makes the standard other-window function skip this. See other-window docs with C-h C-f other-window
There might be a better way to get the current window, but I don't know it yet.
Not the exact answer but I use windmove-mode for that which allow you to use the arrow to visually move between windows and then doing Control-Left or Control-Right to move only between A and B.
Other than that you probably can redefine other-buffer function with something that take buffer-list ignoring some patters when switch-to-buffer to it but I didn't write the code handy.
For the lazy, I use something like this in my .emacs
(fset 'doublejump
"\C-u2\C-xo")
(global-set-key (kbd "C-c o") 'doublejump)
and alternate between using single and double buffer switches.

View the contents of a gzip archive in hexl mode

I want to write a function, similar hexl-find-file, that will open a gzipped file and show the contents in the hexl-mode. How would I do that?
Does this work for you?
(require 'jka-compr)
(defun hexl-find-file ()
"call find file and then jump into hexl mode"
(interactive)
(call-interactively 'find-file)
(hexl-mode 1))
The 'jka-compr provides the seamless compressed file handling, and the 'hexl-find-file just opens the file and turns on hexl-mode.
Turn on auto-compression-mode before you run hexl-find-file?
,----[ C-h f auto-compression-mode RET ]
| `auto-compression-mode' is an interactive compiled Lisp function
| -- loaded from "/usr/share/xemacs21/xemacs-packages/lisp/os-utils/auto-autoloads"
| (auto-compression-mode &optional ARG)
|
| Documentation:
| Toggle automatic file compression and uncompression.
| With prefix argument ARG, turn auto compression on if positive, else off.
| Returns the new status of auto compression (non-nil means on).
|
| Invoked with:
|
| M-x auto-compression-mode
`----