Refactoring in Emacs - emacs

I am working on splitting code into smaller files and refactoring it a bit. Consider the following code below as the section I want to extract:
(require 'package)
(add-to-list 'package-archives
'("marmalade" . "http://marmalade-repo.org/packages/") t)
(package-initialize)
(when (not package-archive-contents)
(package-refresh-contents))
(defvar my-packages '(org magit)
"A list of packages to ensure are installed at launch.")
(dolist (p my-packages)
(when (not (package-installed-p p))
(package-install p)))
I want to take the section above and replace it with something like (require `file-name)
Then take the text replaced and place that in a new file in the current directory named file-name.el
And then add a line to the top of the file (provides `file-name)
It would be great if I could hit a keychord and then type a name and have this happen. If there is an easy way to do this then I would love to hear possible solutions.
Edit:
I'm starting a bounty because I think this applies to more types of code than Lisp and I would like to have something a little more general that I can expand upon.
I have considered yasnippet but I don't think it's powerful enough to perform the task at hand. Basically the ideal workflow would be marking the lines to be extracted, replacing that with an appropriate require or include directive and sending the text off to it's own file. Ideally one command and something that is aware of the type of file being edited or at least the major mode so the behavior can be customized, again yasnippet is good at performing different tasks when editing in different major modes however I would have no idea how to make that work or evaluate the possibility of making it work.
Let me know if you need any more information.

A general solution to this type of problem are keyboard macros (not to be confused with (Emacs) LISP macros). Basically Emacs allows you to record a sequence of keystrokes and "play them back" afterwards. This can be a very handy tool in situations where writing custom LISP code seems overkill.
For instance you could create the following keyboard macro (type the key combinations on the left hand side, the right hand side shows explanations for each key stroke):
C-x ( ; start recording a keyboard macro
C-x h ; mark whole buffer
C-w ; kill region
(require 'file-name) ; insert a require statement into the buffer
C-x C-s ; save buffer
C-x C-f ; find file
file-name.el <RET> ; specify the name of the file
M-< ; move to the beginning of the buffer
C-u C-y ; insert the previously killed text, leaving point where it is
(provide 'file-name) <RET> <RET> ; insert a provide statement into the buffer
C-x ) ; stop recording the keyboard macro
Now you can re-play that macro in some other buffer by typing C-x e, or save it for later use. You can also bind a macro to a shortcut just like a function.
However, there is one weakness with this approach: you want to be able to actually specify the file-name, and not just use the string "file-name" every time. That is a bit difficult - by default, keyboard macros provide no general facility for querying the user (except the very minimal C-x q, as documented here).
The Emacs Wiki has some work-arounds for that, however, instead of prompting the user in the minibuffer, it can sometimes be sufficient to start the macro by killing the current line and saving its text to a register.
C-x (
C-e C-<SPC> C-a ; mark current line
C-x r s T ; copy line to register T
C-k C-k ; kill current line
... ; actual macro
C-x )
Now when you want to use your macro, you would first write the desired file-name in an otherwise empty line, and then do C-x e in that line. Whenever the value of the file-name is needed in the macro you can retrieve it from the register T:
C-x r i T ; insert file-name into buffer
For instance, for the provide statement in the above macro, you could write: (provide ' C-x r i T ). Note that this technique (inserting) also works in the minibuffer, and of course you could save multiple lines to different registers.
May sound complicated, but is actually quite easy in practice.

Slightly tested:
(defun extract-to-package (name start end)
(interactive (list (read-string "Package name to create: ")
(region-beginning) (region-end)))
(let ((snip (buffer-substring start end)))
(delete-region start end)
(insert (format "(require '%s)\n" name))
(with-current-buffer (find-file-noselect (concat name ".el"))
(insert snip)
(insert (format "(provide '%s)\n" name))
(save-buffer))))

For a such thing I use the following snippet (with yasnippet):
;; `(buffer-name)`
;; Copyright (C) `(format-time-string "%Y")` name
;; Author: name <email>
;; This program 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 program 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 program. If not, see <http://www.gnu.org/licenses/>.
$0
(provide '`(subseq (buffer-name) 0 (- (length (buffer-name)) 3))`)
1st create the file C-xC-ffile-name.elRET
then insert the snippet with C-c&C-s
and add any piece of code you wish.
I've also the following hook:
(add-hook 'after-save-hook 'autocompile)
(defun autocompile ()
"Byte compile an elisp."
(interactive)
(require 'bytecomp)
(let ((filename (buffer-file-name)))
(if (string-match "\\.el$" filename)
(byte-compile-file filename))))
to produce an .elc whenever I save a .el.

(defun region-to-file+require (beg end file append)
"Move region text to FILE, and replace it with `(require 'FEATURE)'.
You are prompted for FILE, the name of an Emacs-Lisp file. If FILE
does not yet exist then it is created.
With a prefix argument, the region text is appended to existing FILE.
FEATURE is the relative name of FILE, minus the extension `.el'."
(interactive "#*r\nG\nP")
(when (string= (expand-file-name (buffer-file-name)) (expand-file-name file))
(error "Same file as current"))
(unless (string-match-p ".+[.]el$" file)
(error "File extension must be `.el' (Emacs-Lisp file)"))
(unless (or (region-active-p)
(y-or-n-p "Region is not active. Use it anyway? "))
(error "OK, canceled"))
(unless (> (region-end) (region-beginning)) (error "Region is empty"))
(unless (or (not append)
(and (file-exists-p file) (file-readable-p file))
(y-or-n-p (format "File `%s' does not exist. Create it? " file)))
(error "OK, canceled"))
(write-region beg end file append nil nil (not append))
(delete-region beg end)
(let ((feature (and (string-match "\\(.+\\)[.]el$" file)
(match-string 1 file))))
(when feature
(insert (format "(require '%s)\n" feature)))))

Related

Is there an apply-command-to-each-line-in-region in emacs?

I have a bunch of links saved in an orgmode file, say...
http://www.stackoverflow.com
http://www.google.com
http://www.github.com
I can open each one by having the cursor on the link and doing C-c C-o, and it conveniently pops up my default browser and opens that link in a tab.
Now suppose I have like 20 of these links. Is there a convenient way to apply a function like this to each line within a selected region, without recording an explicit macro?
I'd imagine it looking something like...
Select region
M-x foreach-in-region
Keystrokes to apply to each line: C-c C-o
And this is just for functions already defined. I imagine the way without would be something like...
with cursor on first line of link
F3 # to start record macro
C-c C-o
down arrow
F4
Select region (omitting the first line, since that's now already opened in my browser)
C-x C-k r
Does this exist? If not, how would I lisp this?
You should record the macro for one line, then use apply-macro-to-region-lines to execute it for all lines in region. C-x C-k r
Alternatively, you can use multiple-cursors to create a cursor on each line and C-c C-o to open all. multiple-cursors will transform your usage patterns over time for the better if you give it a chance.
(defun do-lines (fun &optional start end)
"Invoke function FUN on the text of each line from START to END."
(interactive
(let ((fn (intern (completing-read "Function: " obarray 'functionp t))))
(if (use-region-p)
(list fn (region-beginning) (region-end))
(list fn (point-min) (point-max)))))
(save-excursion
(goto-char start)
(while (< (point) end)
(funcall fun (buffer-substring (line-beginning-position) (line-end-position)))
(forward-line 1))))
Update after your comment --
Now it sounds like you want to not enter a function name but hit a key, and have the command bound to that key be applied to each line in the region (or buffer).
Something like the following will do that. However, be aware that command often have particular behavior wrt lines. For example, if you were to hit key C-k (kill-lines) then it already moves forward after each line it kills. Because do-lines does not know what kind of function (command) you will invoke, it advances to the next line after each invocation. For a command such as kill-lines this will thus do the wrong thing: it will end up advancing two lines, not one, thus skipping lines. IOW, be aware that the code for do-lines cannot compensate for what a particular function it invokes might do that might not correspond to what you expect. Instead, it does what it says it does.
(defun do-lines (command &optional start end)
"Invoke COMMAND on the text of each line from START to END."
(interactive
(let* ((key (read-key-sequence-vector "Hit key sequence: "))
(cmd (lookup-key global-map key t)))
(when (numberp cmd) (error "Not a valid key sequence"))
(unless (commandp cmd) (error "Key `%s' is not defined" (key-description key)))
(if (use-region-p)
(list cmd (region-beginning) (region-end))
(list cmd (point-min) (point-max)))))
(setq start (copy-marker start)
end (copy-marker end))
(save-excursion
(goto-char start)
(while (< (point) end)
(funcall command (buffer-substring (line-beginning-position) (line-end-position)))
(forward-line 1))))
In some situations, you can use Emacs Repeating using C-x z following by more `z'. I was trying to comment all the lines in region and it worked nicely for my use case.
The command C-x z (repeat) provides another way to repeat an Emacs
command many times
To repeat the command more than once, type additional z’s: each z repeats the command one more time
In the spirit of TIMTOWTDI[1], I'll point out a technique that works well for some situations, including the one in the OP.
If you're looking to run an external command on a line of space-separated strings (like URLs):
Select the region
Invoke M-| (Alt+Shift+\, shell-command-on-region)
Use xargs as a prefix command to the desired command (e.g., xdg-open, or x-www-browser)
For example, the full command entered for step 3 might be:
xargs -n1 xdg-open
The -n1 switch causes xargs to open invoke the given program with one argument at a time; it will run the program once for each input. If the command can handle multiple arguments at once, you can omit -n1. For example, I have a web command that can open multiple URLs as arguments, so just xargs web works.
The major benefit of this approach is, it works on anything POSIX-compliant without doing anything in advance. Disadvantages include, it only works on external commands, and it requires xargs (not included with every OS by default).
[1] There's More Than One Way To Do It, originally from Perl, but useful elsewhere.

Execute a particular command on multiple emacs buffers

Is there a way to execute emacs command on multiple buffers without having to selecting them individually and executing it on each individual buffer.
I usually open multiple files matching a particular regex, e.g. ~/*.py and wish to enable a particular mode, say hs-minor-mode or glasses-mode on each, or say execute C-c # C-M-h on each. Currently I have to select each one of them and do it individually. So is there a hack or a loop to automate the task.
Lets say I mark the buffers from the buffer-list and then run the command for all those marked.
I tried this but after executing the commands in eval-expression I completely lost access to my minibuffer, meaning whenever I typed M-x the minibuffer returned this
unable to access the minibuffer emacs error "Process Menu Mode doesn't support Hideshow Minor Mode"
and I was forced to actually kill the entire emacs process because the C-x C-s wasn't working neither was the End Task.
PS: I have no experience in elisp
You can use ibuffer mode for this (It is part of the default Emacs distribution).
(global-set-key "\C-x\C-b" 'ibuffer) ;; make ibuffer the default
In *Ibuffer* you can mark the required buffers with m and then
execute a form in each with E.
Generally, ibuffer is a lot more flexible then the usual buffer list and I think ibuffer should really be the default buffer-list in Emacs.
If you do this often, you might want to switch those particular modes on every time you enter python mode by attaching them to the mode-hook:
(add-hook 'python-mode-hook 'hs-minor-mode)
(add-hook 'python-mode-hook 'glasses-mode)
I didn't know ibuffer had that feature!
Anyway, for those who are more familiar with dired, here is a command that do the same. Select the files in dired with m or any other more powerful method. Then do, M-xdired-do-command and write a form or a command just as in M-x.
(defun dired-do-command (command)
"Run COMMAND on marked files. Any files not already open will be opened.
After this command has been run, any buffers it's modified will remain
open and unsaved."
(interactive
(list
(let ((print-level nil)
(minibuffer-history-position 0)
(minibuffer-history-sexp-flag (1+ (minibuffer-depth))))
(unwind-protect
(read-from-minibuffer
"Command: " (prin1-to-string (nth 0 command-history))
read-expression-map t
(cons 'command-history 0))
;; If command was added to command-history as a
;; string, get rid of that. We want only
;; evaluable expressions there.
(if (stringp (car command-history))
(setq command-history (cdr command-history)))))))
(dolist (filename (dired-get-marked-files))
(with-current-buffer (find-file-noselect filename)
(if (symbolp command)
(call-interactively command)
(eval command)))))

Emacs org-mode: textual reference to a file:line

I am using org-mode in Emacs to document my development activities. One of the tasks which I must continuously do by hand is to describe areas of code. Emacs has a very nice Bookmark List: create a bookmark with CTRL-x r m, list them with CTRL-x r l. This is very useful, but is not quite what I need.
Org-mode has the concept of link, and the command org-store-link will record a link to the current position in any file, which can be pasted to the org-file. The problem with this is two-fold:
It is stored as an org-link, and the linked position is not directly visible (just the description).
It is stored in the format file/search, which is not what I want.
I need to have the bookmark in textual form, so that I can copy paste it into org-mode, end edit it if needed, with a simple format like this:
absolute-file-path:line
And this must be obtained from the current point position. The workflow would be as simple as:
Go to the position which I want to record
Call a function: position-to-kill-ring (I would bind this to a keyboard shortcut)
Go to the org-mode buffer.
Yank the position.
Edit if needed (sometimes I need to change absolute paths by relative paths, since my code is in a different location in different machines)
Unfortunately my lisp is non-existent, so I do not know how to do this. Is there a simple solution to my problem?
(defun position-to-kill-ring ()
"Copy to the kill ring a string in the format \"file-name:line-number\"
for the current buffer's file name, and the line number at point."
(interactive)
(kill-new
(format "%s:%d" (buffer-file-name) (save-restriction
(widen) (line-number-at-pos)))))
You want to use the org-create-file-search-functions and org-execute-file-search-functions hooks.
For example, if you need the search you describe for text-mode files, use this:
(add-hook 'org-create-file-search-functions
'(lambda ()
(when (eq major-mode 'text-mode)
(number-to-string (line-number-at-pos)))))
(add-hook 'org-execute-file-search-functions
'(lambda (search-string)
(when (eq major-mode 'text-mode)
(goto-line (string-to-number search-string)))))
Then M-x org-store-link RET will do the right thing (store a line number as the search string) and C-c C-o (i.e. M-x org-open-at-point RET) will open the file and go to this line number.
You can of course check for other modes and/or conditions.
An elisp beginner myself I though of it as a good exercise et voila:
Edit: Rewrote it using the format methode, but I still think not storing it to the kill-ring is less intrusive in my workflow (don't know about you). Also I have added the capability to add column position.
(defvar current-file-reference "" "Global variable to store the current file reference")
(defun store-file-line-and-col ()
"Stores the current file, line and column point is at in a string in format \"file-name:line-number-column-number\". Insert the string using \"insert-file-reference\"."
(interactive)
(setq current-file-reference (format "%s:%d:%d" (buffer-file-name) (line-number-at-pos) (current-column))))
(defun store-file-and-line ()
"Stores the current file and line oint is at in a string in format \"file-name:line-number\". Insert the string using \"insert-file-reference\"."
(interactive)
(setq current-file-reference (format "%s:%d" (buffer-file-name) (line-number-at-pos))))
(defun insert-file-reference ()
"Inserts the value stored for current-file-reference at point."
(interactive)
(if (string= "" current-file-reference)
(message "No current file/line/column set!")
(insert current-file-reference)))
Not tested extensively but working for me. Just hit store-file-and-line or store-file-line-and-col to store current location and insert-file-reference to insert the stored value at point.
BTW, if you want something better than FILE:LINE, you can try to use add-log-current-defun (in add-log.el) which should return the name of the current function.
;; Insert a org link to the function in the next window
(defun insert-org-link-to-func ()
(interactive)
(insert (with-current-buffer (window-buffer (next-window))
(org-make-link-string
(concat "file:" (buffer-file-name)
"::" (number-to-string (line-number-at-pos)))
(which-function)
))))
This func generates link with the function name as the description.
Open two windows, one is the org file and the other is src code.
Then M-x insert-org-link-to-func RET

How to open multiple terminals?

In Emacs, I often find myself in a situation where I need to jump back and forth between various source files to various terminals. However, I feel like I do not have a good way to do this efficiently and it's clumsy that you can only open one shell in Emacs (shell, eshell, or term).
Moreover, I need an efficient way of juggle between multiple terminals and source files.
How can I achieve this?
You can have as many terminals and shells open at once as you want. Just use M-x rename-buffer to change the name of an existing *term* or *shell* buffer, and the next time you do M-x term or M-x shell, a brand new buffer will be created. In the case of M-x shell, a prefix argument will cause you to be prompted for the name of the new shell buffer, as offby1 noted.
A few years ago I had a job where I had to regularly log in to various production servers named "host01.foo.com", "host02.foo.com", etc. I wrote a little function like this one to make it easier to manage them all:
(defun ssh-to-host (num)
(interactive "P")
(let* ((buffer-name (format "*host%02d*" num))
(buffer (get-buffer buffer-name)))
(if buffer
(switch-to-buffer buffer)
(term "/bin/bash")
(term-send-string
(get-buffer-process (rename-buffer buffer-name))
(format "ssh host%02d.foo.com\r" num)))))
Then I bound this command to (say) s-h (super H), enabling me to just type M-5 s-h. If I didn't already have a buffer named *host05*, it would start a new terminal emulator buffer, rename it to *host05*, and ssh me into host05.foo.com. If buffer *host05* already existed, it would simply switch me to it. Quite handy!
You can certainly have multiple interactive shells open. Try typing C-u M-x shell RET RET.
Try using MultiTerm to open multiple shells.
You can use Emacs Lisp Screen, which emulates GNU Screen and provides easy key bindings to jump to and between a number of different shells.
I use many methods for incorporating my terminal life into Emacs:
elscreen.el is a life saver, if you have a complicated window layout like gdb or have simply become overwhelmed with clutter you just open a new screen. In your case you could dedicate one screen to terminals.
multi-term.el makes managing terminals a bit easier.
shell-pop.el, a great tool for quick terminal access. shell-pop lets you assign a key to opening and closing a specific shell buffer window, if you've used drop-down terminals like tilda you know how incredibly handy this can be:
Here's and example of my shell-pop configuration, I use the key C-t to pop up an eshell:
(require 'shell-pop)
(shell-pop-set-internal-mode "eshell") ; Or "ansi-term" if you prefer
(shell-pop-set-window-height 60) ; Give shell buffer 60% of window
;; If you use "ansi-term" and want to use C-t
;; (defvar ansi-term-after-hook nil)
;; (add-hook 'ansi-term-after-hook
;; '(lambda ()
;; (define-key term-raw-map (kbd "C-t") 'shell-pop)))
;; (defadvice ansi-term (after ansi-term-after-advice (org))
;; (run-hooks 'ansi-term-after-hook))
;; (ad-activate 'ansi-term)
(global-set-key (kbd "C-t") 'shell-pop)
I usually do an an M-x server-start and then use emacsclient --no-wait to open files. I've aliased that to e with some embellishments so that it's a little more convenient.
I do all my work in a single terminal and just "throw" the files I want to edit into Emacs using e. Inside Emacs, I juggle around using iswitchb and it works just fine. YMMV.
I regularly used 10 or so shells in my old workplace. The secret is you have to rename additional shell buffers. I did this automatically though in my .emacs, creating and naming the shells logically (I had projnameRun and projnameBuild for every project). Worked really well together with anything, making it very easy to refind the right shell (you use the end of the project name combined with either r or b for run/build).
Instead of having several terminal windows in emacs, I spawn a different xterm whenever I need a new terminal. This of course is bearable because I use a very lightweight terminal emulator (urxvt) which starts in under 0.2s.
Then I use my window manager to switch between them and emacs frames. A configurable window manager will have plenty of options to tune to switch between windows (extremely) efficiently. Inside emacs, I use windmove and ido-mode, and have bound to C-tab a function that switches to the last buffer (because I use C-x b in that fashion a lot).
So um, not sure how useful it is to you since it's quite different from your use pattern, but this is what works for me.
I had exactly the same problem some years ago, and found nothing that satisfied me; so I wrote my own "toggle shell" function. It toggles between the current frame or window configuration and a system shell buffer. It can also put the shell into a dedicated frame, and inject a pushd to the current buffer directory.
This is an excerpt from my .emacs:
(defvar --toggle-shell-last-window-conf nil "The last window configuration.")
(defvar --toggle-shell-last-buf nil "The last buffer object in case there's no last window configuration.")
(defvar --toggle-shell-last-frame nil "The frame that was selected when opening a shell buffer.")
(defun --toggle-shell-have-conf ()
(window-configuration-p --toggle-shell-last-window-conf))
(defun --toggle-shell-store-last-conf ()
(setq --toggle-shell-last-buf (current-buffer)
--toggle-shell-last-frame (selected-frame)
--toggle-shell-last-window-conf (current-window-configuration)))
(defun --toggle-shell-restore-last-conf ()
(if (--toggle-shell-have-conf)
(progn (raise-frame --toggle-shell-last-frame)
(set-window-configuration --toggle-shell-last-window-conf))
(let ((bufnam (if (bufferp --toggle-shell-last-buf)
(buffer-name --toggle-shell-last-buf) --toggle-shell-last-buf)))
(if bufnam
(if (get-buffer bufnam) (switch-to-buffer bufnam t)
(message "%s: buffer not available" bufnam))))))
(defun --toggle-shell (&optional display inject-cd)
"Toggles between current buffers and a system shell buffer. With prefix-arg
close the shell.
When DISPLAY is 'vertical splits the shell as vertical window; when 'frame uses
a dedicated frame (default: single window). When INJECT-CD executes a `pushd'
to the working directory of the buffer from which you toggled the shell."
(interactive)
(let* ((shell-buf (get-buffer "*shell*"))
(shell-window ; non-nil when currently displayed
(if shell-buf (get-buffer-window shell-buf t)))
(shell-frame
(if shell-window (window-frame shell-window)))
(in-shell (eq (current-buffer) shell-buf))
(vertical (string= display 'vertical))
(popup-frame (or (string= display 'frame)
(and inject-cd (not (bufferp shell-buf)))
(and (framep shell-frame)
(not (eq shell-frame (selected-frame)))))))
;; With prefix-arg close shell, restore windows. Otherwise (no prefix-arg)
;; toggle shell window; restore windows when called twice in a row, or the
;; current buffer is the shell buffer (`in-shell').
(if current-prefix-arg
(if (bufferp shell-buf)
(progn (message "Exiting shell '%s'" (buffer-name shell-buf))
(kill-buffer shell-buf)
(if in-shell (--toggle-shell-restore-last-conf)))
(error "No shell buffer to kill."))
;; If already in shell-buffer toggle back to stored frame-configuration.
(if (and in-shell (not inject-cd))
(progn
(--toggle-shell-restore-last-conf)
;; Recurse to reopen the shell-buffer in a dedicated frame, or
;; close the dedicated frame and reopen the buffer in a window.
(if (and popup-frame (eq shell-frame (selected-frame)))
(--toggle-shell 'frame inject-cd)
(when (and popup-frame shell-frame)
(delete-frame shell-frame)
(--toggle-shell nil inject-cd))))
;; Not in shell buffer. Warp to it or create new one.
(unless in-shell
(--toggle-shell-store-last-conf))
(if popup-frame
(progn (switch-to-buffer-other-frame (or shell-buf "*shell*"))
(raise-frame
(or shell-frame (window-frame (get-buffer-window "*shell*" t)))))
(if (> (count-windows) 1)
(delete-other-windows)))
;; Finally `cd' into the working directory the current buffer.
(let ((new-shell (not (bufferp shell-buf)))
(new-dir ; `default-directory' of `--toggle-shell-last-buf'
(if --toggle-shell-last-buf
(buffer-local-value 'default-directory --toggle-shell-last-buf))))
;; Open shell, move point to end-of-buffer. The new shell-buffer's
;; `default-directory' will be that of the buffer the shell was
;; launched from.
(when vertical
(if (> (count-windows) 1)
(delete-other-windows))
(split-window-vertically) (other-window 1))
(funcall 'shell)
(when new-shell
(message "New shell %s (%s)" (buffer-name (current-buffer)) new-dir)
(if inject-cd (sit-for 2))) ; wait for prompt
(goto-char (point-max))
;; If on a command-prompt insert and launch a "cd" command (assume no
;; job is running).
(when (and inject-cd new-dir)
(save-excursion
(backward-line-nomark) (end-of-line)
(unless (setq inject-cd (re-search-forward comint-prompt-regexp (point-max) t))
(error "Cannot `pushd', shell is busy")))
(when (and inject-cd)
(let* ((cmd (format
"pushd '%s' %s" (comint-quote-filename new-dir)
(if (buffer-file-name --toggle-shell-last-buf)
(format "# '%s'" (file-name-directory (buffer-file-name --toggle-shell-last-buf)))
""))))
;; `shell-process-cd' set new `default-directory' and set
;; `shell-last-dir' to old. (If the pushd command is
;; successful, a dirs is performed as well; >nul discards this
;; output.)
(shell-process-cd new-dir)
(insert cmd)
(comint-send-input)
(message "%s: cd '%s'" (buffer-name --toggle-shell-last-buf) new-dir))
)
)
)
)
)
)
)
--toggle-shell is the function that does the trick. I bind it to F12:
;; F12 toggle between shell buffer and current window configuration
;; SHIFT-F12 like before, but let shell buffer appear in a dedicated frame
;; ALT-F12 inject a pushd to change to directory of current buffer
;; CTRL-F12 `shell-command'
(global-set-key [(f12)] '--toggle-shell)
(global-set-key [(shift f12)] '(lambda()(interactive)(--toggle-shell 'frame)))
(global-set-key [(meta f12)] '(lambda()(interactive)(--toggle-shell nil t)))
(global-set-key [(meta f10)] '(lambda()(interactive)(--toggle-shell nil t)))
(global-set-key [(control f12)] 'shell-command) ; alias M-!
This is a significant bunch of code to be posted here. But it shall work well.
Semi related - you can quickly run a shell command on selected file with
M+shift+!
It saves a lot of time for smaller commands chmod etc
And maybe my quick pop-up shell also might help you. A quick pop-up shell for emacs
Ecb + eshell will be what you want exactly!
I use vi, but hope this helps. I can open as many terminals as I want by (eg. in Ubuntu 16.04):
ctrl + alt + t
I usually open 2 terminals, and move (position) one terminal to the right by:
ctrl + super + right-arrow
and move the other terminal to the left by:
ctrl + super + left-arrow
so that I have a divided screen by 2 terminals.

How do I change read/write mode for a file using Emacs?

If a file is set to read only mode, how do I change it to write mode and vice versa from within Emacs?
M-x read-only-mode
in very old versions of Emacs, the command was:
M-x toggle-read-only
On my Windows box, that amounts to Alt-x to bring up the meta prompt and typing "read-only-mode" to call the correct elisp function.
If you are using the default keyboard bindings,
C-x C-q
(which you read aloud as "Control-X Control-Q") will have the same effect. Remember, however, given that emacs is essentially infinitely re-configurable, your mileage may vary.
Following up from the commentary: you should note that the writeable status of the buffer does not change the writeable permission of the file. If you try to write out to a read only file, you'll see a confirmation message. However, if you own the file, you can write out your changes without changing the permissions on the file.
This is very convenient if you'd like to make a quick change to a file without having to go through the multiple steps of add write permission, write out changes, remove write permission. I tend to forget that last step, leaving potentially critical files open for accidental changes later on.
Be sure you're not confusing 'file' with 'buffer'. You can set buffers to read-only and back again with C-x C-q (toggle-read-only). If you have permission to read, but not write, a file, the buffer you get when you visit the file (C-x C-f or find-file) will be put in read-only mode automatically. If you want to change the permissions on a file in the file system, perhaps start with dired on the directory that contains the file. Documentation for dired can be found in info; C-h i (emacs)dired RET.
What I found is M-x set-file-modes filename mode
It worked at my Windows Vista box.
For example: M-x set-file-modes <RET> ReadOnlyFile.txt <RET> 0666
As mentioned up there by somebody else: M-x toggle-read-only would work.
However, this is now deprecated and M-x read-only-mode is the current way to do it, that it is set to C-x C-q keybinding.
CTRL + X + CTRL + Q
If only the buffer (and not the file) is read-only, you can use toggle-read-only, which is usually bound to C-x C-q.
If the file itself is read-only, however, you may find the following function useful:
(defun set-buffer-file-writable ()
"Make the file shown in the current buffer writable.
Make the buffer writable as well."
(interactive)
(unix-output "chmod" "+w" (buffer-file-name))
(toggle-read-only nil)
(message (trim-right '(?\n) (unix-output "ls" "-l" (buffer-file-name)))))
The function depends on unix-output and trim-right:
(defun unix-output (command &rest args)
"Run a unix command and, if it returns 0, return the output as a string.
Otherwise, signal an error. The error message is the first line of the output."
(let ((output-buffer (generate-new-buffer "*stdout*")))
(unwind-protect
(let ((return-value (apply 'call-process command nil
output-buffer nil args)))
(set-buffer output-buffer)
(save-excursion
(unless (= return-value 0)
(goto-char (point-min))
(end-of-line)
(if (= (point-min) (point))
(error "Command failed: %s%s" command
(with-output-to-string
(dolist (arg args)
(princ " ")
(princ arg))))
(error "%s" (buffer-substring-no-properties (point-min)
(point)))))
(buffer-substring-no-properties (point-min) (point-max))))
(kill-buffer output-buffer))))
(defun trim-right (bag string &optional start end)
(setq bag (if (eq bag t) '(?\ ?\n ?\t ?\v ?\r ?\f) bag)
start (or start 0)
end (or end (length string)))
(while (and (> end 0)
(member (aref string (1- end)) bag))
(decf end))
(substring string start end))
Place the functions in your ~/.emacs.el, evaluate them (or restart emacs). You can then make the file in the current buffer writable with M-x set-buffer-file-writable.
If you are looking at a directory of files (dired), then you can use Shift + M on a filename and enter the modespec, the same attributes used in the chmod command.
M modespec <RET>
See the other useful commands on files in a directory listing at
http://www.gnu.org/s/libtool/manual/emacs/Operating-on-Files.html
I tried out Vebjorn Ljosa's solution, and it turned out that at least in my Emacs (22.3.1) there isn't such function as 'trim-right', which is used for removing an useless newline at the end of chmod output.
Removing the call to 'trim-right' helped, but made the status row "bounce" because of the extra newline.
C-x C-q is useless. Because your also need the permission to save a file.
I use Spacemacs. It gives me a convenient function to solve this question. The code is following.
(defun spacemacs/sudo-edit (&optional arg)
(interactive "p")
(if (or arg (not buffer-file-name))
(find-file (concat "/sudo:root#localhost:" (ido-read-file-name "File: ")))
(find-alternate-file (concat "/sudo:root#localhost:" buffer-file-name))))
I call spacemacs/sudo-edit to open a file in emacs and input my password, I can change the file without read-only mode.
You can write a new function like spacemacs/sudo-edit.