I have the following emacs lisp snippet that will launch my browser from within emacs and open the specified pages. However when I run it as a script from a shell nothing happens. What more do I need to do? I tried dropping (interactive).
#!/usr/bin/emacs --script
(defun surf-news ()
(interactive)
(progn
(browse-url "http://news.ycombinator.com")
(browse-url "http://stackoverflow.com")
))
(surf-news)
A neat function I discovered yesterday is M-x webjump which has recently been added to emacs.
As Ryan Thompson mentioned above, you can use xdg-open in Emacs.
Change:
(browse-url "http://news.ycombinator.com")
(browse-url "http://stackoverflow.com")
To:
(browse-url-xdg-open "http://news.ycombinator.com")
(browse-url-xdg-open "http://stackoverflow.com"))
I found the answer on this site, at the bottom, where it describes a Mac OS pty bug. I had to add this line and a slight delay between urls.
(setq process-connection-type nil)
Here's the complete solution.
#!/usr/bin/emacs --script
(setq process-connection-type nil);; pty's broken on the Mac
(defun surf ()
(progn
(browse-url "http://news.ycombinator.com")
(sleep-for 0.5); We need a delay
(browse-url "http://stackoverflow.com")
))
;;
;; This is what's going on behind the scenes
;;(setq url "http://www.google.com")
;;(start-process (concat "open " url) nil "open" url)
(surf)
On linux, if you are in GNOME, KDE, or probably almost any graphical environment, there is probably a command called xdg-open. This command basically takes its argument and opens it with the desktop default application. It handles both files and URLs. So generally when I need to say "Open this in the default application," I use xdg-open.
I think Mac OS has a similar command just called open.
Related
I work a lot in a shell inside emacs (on a Mac). It used to be that, when I typed control-Q control-C, that would kill a process running in the shell. About a year ago, though, that stopped working for some reason; now it has no effect. Anyone know why, or another way of doing this?
I had the same problem using term-mode.
I bound term-interrupt-subjob to my keybinding of choice with:
(add-hook 'term-mode-hook (lambda ()
(define-key term-raw-map (kbd "C-'") 'term-interrupt-subjob)
I am not sure which mode you are using to interact with a shell from Emacs (the inferior shell, Emacs shell, or the terminal emulator). So you might have to modify this a little by replacing term-interrupt-subjob by, for instance, comint-interrupt-subjob and changing the mode hook.
To answer your questions in the comments:
You add the function in your .emacs file. For it to take effect, you need to evaluate it: you can select it and run M-x eval-region or you can restart Emacs.
If you are running M-x shell, you are using shell-mode.
Note that to know which major mode you are using, you can run describe-mode.
Since you are using shell-mode, you want to use add-hook 'shell-mode-hook instead of add-hook 'term-mode-hook and shell-mode-map instead of term-raw-map.
However, in shell-mode, C-c C-c does by default run the command comint-interrupt-subjob. So this should work out of the box as Rorschach said. I am not sure why it isn't working for you.
You can try:
(add-hook 'shell-mode-hook (lambda ()
(define-key shell-mode-map (kbd "C-c C-c") 'comint-interrupt-subjob)
to see if that helps. But this should already be set since it is the default, so it is really unclear whether it will solve your problem.
My setup:
Emacs terminal mode (emacs -nw)
inside it, use the shell mode (invoked with M-x ansi-term)
inside this shell, connect to a remote server with ssh
Suppose I'm browsing the remote server inside the shell and find a file I want to edit. Is there a command to open it as a parallel buffer/window?
The only method I know to open a file from the shell is to do emacs -nw again, which isn't quite convenient because a) I don't keep the shell open and b) it's really a different Emacs session, so for instance the "yank buffer" is different.
Edit: if there is a different/better way to work with a remote server with Emacs I'm just as interested; it's what I'm trying to do.
It's best to use tramp.
I have this shortcut (I call it with smex):
(defun connect-remote ()
(interactive)
(dired "/user#domain.com:/"))
This opens a dired buffer on the remote. You just use it as any dired buffer.
I've had a function to open a term from dired for a while, but I've
added an option to ssh from a tramp dired buffer just now:
(defun dired-open-term ()
"Open an `ansi-term' that corresponds to current directory."
(interactive)
(let ((current-dir (dired-current-directory)))
(term-send-string
(terminal)
(if (file-remote-p current-dir)
(let ((v (tramp-dissect-file-name current-dir t)))
(format "ssh %s#%s\n"
(aref v 1) (aref v 2)))
(format "cd '%s'\n" current-dir)))))
(defun terminal ()
"Switch to terminal. Launch if nonexistent."
(interactive)
(if (get-buffer "*terminal*")
(switch-to-buffer "*terminal*")
(term "/bin/bash")))
And this is the shortcut that I use:
(define-key dired-mode-map (kbd "`") 'dired-open-term)
You could use tramp from within your original emacs session to browse the remote server via ssh, using dired. Then, any remote file you open is opened in your local emacs session.
If you prefer to avoid dired and want to browse with a shell, you can prepend the remote location (/name#host:/path/from/pwd) to the file name. You can automate that with a function.
If I understand correctly, when running bash under M-x shell, Emacs overrides some of the bash keyboard bindings, and can make some bash commands and features not work as in "native bash" (for an example see this thread)
One of the commands that I use frequently in bash is clear-screen (bounded to Ctrl-l by default ).
Is there an easy way of asking Emacs to reproduce the same behavior in shell-mode so that I can clear my bash screen within Emacs?
I know I can always use M-x term to get a real terminal, but I would like to work out a solution for M-x shell
EDIT: When I type C-l C-l, Emacs moves the current line to the top of the window, but as soon as I enter a new command in bash, the window is scrolled again to the original position.
Thanks
Just type M-> to go to the bottom of the buffer (if necessary), then C-l C-l to move the current line to the top of the window. It looks as if you've cleared your screen, but all of the content that would have been erased is still present above the top of the window.
EDIT:
To keep Emacs from scrolling the window as you described, put this in your .emacs file:
(remove-hook 'comint-output-filter-functions
'comint-postoutput-scroll-to-bottom)
I found that behavior irritating as well.
You could re-bind C-l in shell mode to make it function in the manner you want:
(define-key shell-mode-map (kbd "C-l")
(lambda ()
(interactive)
(previous-line)
(end-of-line)
(let ((start (point))
(end (goto-char (point-min))))
(delete-region start end)
(kill-line)
(end-of-buffer))))
As explained in here, putting (setq default-directory "~/Desktop/mag" ) in .emacs is supposed to change the default directory.
When I do that with the emacs on my mac, it doesn't work. C-x C-f still shows ~/ not ~/Desktop/mag.
(cd "Users/smcho/Desktop/mag") also gives me this error - Error: No such directory found via CDPATH environment variable
What's wrong with them?
The directory that appears in the prompt for C-x C-f ('find-file') comes from the value of default-directory, which is a buffer-local variable. When you first start Emacs, the initial buffer displayed is the GNU Emacs buffer. That buffer's default-directory is set from the variable command-line-default-directory.
So, try this:
(setq command-line-default-directory "~/Desktop/mag")
The straight-forward answer to your question is:
(setq-default default-directory "~/Desktop/mag")
Reading the documentation for the variable (C-h v default-directory RET) you'll see:
Automatically becomes buffer-local
when set in any fashion. This
variable is safe as a file local
variable if its value satisfies the
predicate `stringp'.
That said, opening a file automatically sets the default-directory to the path of the file...
So, if you always want find-file to start at that directory, you can use this:
(global-set-key (kbd "C-x C-f") 'my-find-file)
(defun my-find-file ()
"force a starting path"
(interactive)
(let ((default-directory "~/scratch/"))
(call-interactively 'find-file)))
This question may be a duplicate of Preventing automatic change of default-directory. Though it's difficult to tell.
In addition to the notes above regarding default-directory, I had to also prevent the emacs splash screen from starting in order to make subsequent commands like dired actually show their buffer when invoked from .emacs on startup:
(setq inhibit-splash-screen t)
I have configured my emacs to run zsh shell within ansi-term. However, copy/paste no longer works i.e. nothing is getting pasted from kill-ring to the terminal.
Changing the TERM to vt100, or eterm doesn't solve the problem.
Would appreciate any ideas or solution.
To provide context I have configured ansi-term as follows:
(global-set-key "\C-x\C-a" '(lambda ()(interactive)(ansi-term "/bin/zsh")))
(global-set-key "\C-x\ a" '(lambda ()(interactive)(ansi-term "/bin/zsh")))
You may want to simply switch between character mode and line mode while using the terminal. C-c C-j will run term-line-mode, which treats the terminal buffer more like a normal text-buffer in which you can move the cursor and yank text. You can switch back to character mode by running term-char-mode with C-c C-k.
As described in this lovely blog snippet, there's a function, term-paste, in term.el, that does exactly what you want. By default it's bound only to S-insert but the blog's recommended C-c C-y seems like a good suggestion.
ansi-term, in char-mode, takes the ordinary bindings for the terminal emulation. You need a new binding, plus a way to output to ansi-term correctly. I use this:
(defun ash-term-hooks ()
;; dabbrev-expand in term
(define-key term-raw-escape-map "/"
(lambda ()
(interactive)
(let ((beg (point)))
(dabbrev-expand nil)
(kill-region beg (point)))
(term-send-raw-string (substring-no-properties (current-kill 0)))))
;; yank in term (bound to C-c C-y)
(define-key term-raw-escape-map "\C-y"
(lambda ()
(interactive)
(term-send-raw-string (current-kill 0)))))
(add-hook 'term-mode-hook 'ash-term-hooks)
When you do this, C-c C-y will yank. It only does one yank, though, and you can't cycle through your kill-buffer. It's possible to do this, but I haven't implemented it yet.
The above solutions work well for copying text from some buffer to ansi-term, but they aren't able to copy text from ansi-term to another buffer (eg copy a command you just ran to a shell script you're editing). Adding this to my .emacs file solved that problem for me (in Emacs 24.4):
(defun my-term-mode-hook ()
(define-key term-raw-map (kbd "C-y") 'term-paste)
(define-key term-raw-map (kbd "C-k")
(lambda ()
(interactive)
(term-send-raw-string "\C-k")
(kill-line))))
(add-hook 'term-mode-hook 'my-term-mode-hook)
Note that if you want to bind kill/yank to a keystroke that starts with the ansi-term escape characters (by default C-c and C-x), and want this to work in the unlikely event that those change, you can instead define your keystrokes (without the leading escape) to term-raw-escape-map, as is done in user347585's answer.
These other solutions don't work well for me, switching between character mode and line mode causes ansi-term to stop working properly randomly, and setting ansi-term's term-paste to C-c C-y (based on Glyph's link), didn't work the code snippet was for term, not ansi-term:
(eval-after-load "ansi-term"
'(define-key ansi-term-raw-map (kbd "C-c C-y") 'term-paste))
I enabled xterm-mouse-mode, after that I was able to select text using mouse and copy using standard Mac command C button in ansi-term in emacs GUI in Mac OS X,