I'm wondering if a kind elisp expert can write this gdb-pounce fn, which
will make emacs wait for a process to start, get it's pid, and tell the running
gdb to attach to it. The command should display "Waiting for 'process' to start..."
and pressing any key should quit the function.
Getting the pid is one of the easier part:
;; The command which will get the PID
(setq cmd ( format "ps -u %s -o pid,fname | awk '{ if ( \"%s\" == $2 ) print($1)}"
(user-login-name)
binary))
(set maybe_pid (shell-command-to-string cmd) )
The place, where elisp expert is needed, is how to call this every 1 second, or till the
user presses a key to exit.
Thanks in advance.
UPDATE:
The script is here: https://bitbucket.org/vrdhn/gdb-pounce/raw/master/gdb-pounce.el
You could do something like this:
(let ((done nil))
(while (and (not done) (not (input-pending-p)))
(if (> (random 10) 7)
(setq done t)
(message "Waiting...")
(sleep-for 1))))
I put in the random check here just as an example; that's where you'd put the check for the process. The key parts are input-pending-p and sleep-for.
Related
I want to read the output of a buffer after process started by comint finishes.
(comint-redirect-send-command-to-process
command-string ;; tested to work in the commint buffer
output-buffer-name ;; random text
buffer-process ;; (get-buffer-process (current-buffer))
nil ;; don't echo input back
t) ;; don't show output buffer immediatly
This sexp is evaluated in a buffer running a comint process. I want to read all the text of output-buffer-name once the process has finished.
I have tried applying the solution posted to this question: sleep in emacs lisp by adding this below the process start command:
(defun on-status-change (process status)
(message "status done"))
(set-process-sentinel buffer-process 'on-status-change)
This message does not appear in *Messages*.
There is no prompt in the output-buffer text, but I can write a function that returns t when the output is finished based on the full output text.
How can I react to the buffer finishing/changing, or how can I force comint to run this function synchronously.
The source for comint-redirect-send-command-to-process is here on line 3717
If anyone else has a similar issue, I ended up "solving" this.
(while (not comint-redirect-completed)
(sleep-for 0.01))
comint-redirect-completed’s value is nil
Documentation:
Non-nil if redirection has completed in the current buffer.
Obviously not a great solution, but I couldn't get anything else working.
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.
During the compilation of sources, I would like GNU Make to call an emacs defun.
For this I have 2 options:
Start a new emacs instance, and load the desired function and call it.
Call the defun from the emacsclient like:
emacsclient --eval "(my-emacs-defun)"
The latter has the advantage, it is faster, because the emacs server is already running and has the desired defun loaded.
But this also has a disadvantage, if (message ...) is called from (my-emacs-defun), it interrupts my active emacs session.
I could try to modify (my-emacs-defun) so (message ...) isn't called, but is really hard when using emacs built-in functions.
Therefore I would like to know how to suppress the (message ...) from (my-emacs-defun).
Is it possible to alter the (message ...) behavior when being called (my-emacs-defun)? Can I use(defadvice)` for this?
EDIT
The real problem is, the message is displayed the minibuffer. It is irritating when using the minibuffer at that time (e.g. during (find-file)).
Just redefine the message function for your call (temporarily):
(flet ((message (msg) ))
(my-emacs-defun)))
Because of dynamic scoping for global functions, the name message will be redefined while the execution is inside the flet-expression, and it will return it's original sense after it exits the flet.
Example:
(defun verbose ()
(message "hi"))
(let ()
(message "one")
(flet ((message (msg) ))
(verbose))
(message "two"))
; ->
; one
; two
You could've also temporarily rebind s Messages buffer, but I don't know where is it stored.
You can restore the message displayed in the echo area before the function call like this:
(let ((msg (current-message)))
(do-something-that-calls-message)
(message "%s" (or msg "")))
(with-temp-message "" (my-emacs-func))
I've looked in the emacs source code and I found this hack:
(let ((message-log-max nil)
(executing-kbd-macro t))
(my-emacs-defun))
This does suppress all message, but still while (find-file) the focus of the minibuffer is lost.
I decided to go for the first option: without emacsclient.
To be more precise I now use:
emacs --batch --eval "(my-emacs-defun)"
In my Makefile it looks like this:
sometarget:
#emacs --batch --eval "$${elisp_code}"
define elisp_code
(require 'something)
(my-emacs-defun)
endif
This also seems to be fast.
Even better:
define emacs_script_content=
(require 'something)
(my-emacs-defun)
endef
export emacs_script_content
emacs-script:
#echo $${emacs_script_content} > $#
.INTERMEDIATE: emacs-script
some-target: emacs-script
#emacs --script $<
This way you won't get errors when calling make functions or when having quoted "text" in the script.
My ~/.emacs contains the following settings for opening certain files with certain applications (Ubuntu 12.10; Emacs 24):
(setq dired-guess-shell-alist-user
'(("\\.pdf\\'" "okular ? &")
("\\.djvu\\'" "okular ? &")
("\\.mp3\\'" "vlc ? &")
("\\.mp4\\'" "vlc ? &")
))
When I navigate to a .pdf in dired-mode and hit !, it opens the .pdf in Okular, but the dired-buffer is split into two parts, the second one now being a useless *Async Shell Command* buffer containing content like
okular(25393)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(25393)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(25393)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(25393)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
How can I prevent this buffer from being opened? (except for, maybe, if there was an error and this information is useful).
I found related questions here and here, but they seem to deal with specific commands executed asynchronously, instead of the *Async Shell Command* in general (if possible, I would like to change the behaviour in general for asynchronous processes, not only for certain file types)
Found this here:
(call-process-shell-command "okular&" nil 0)
Works for me. No stderr gobbledygook.
The question was asked in 2012, and at the time of my writing, the most recent answer is dated 2015. Now, in 2017, I can say that the answer is simple:
(add-to-list 'display-buffer-alist
(cons "\\*Async Shell Command\\*.*" (cons #'display-buffer-no-window nil)))
I am piggybacking off of user1404316's answer, but here is another generic way to achieve the desired outcome.
(defun async-shell-command-no-window
(command)
(interactive)
(let
((display-buffer-alist
(list
(cons
"\\*Async Shell Command\\*.*"
(cons #'display-buffer-no-window nil)))))
(async-shell-command
command)))
I'm not entirely sure about doing it for asynchronous processes in general, but for anything that goes through async-shell-command, this should work:
(defadvice async-shell-command (around hide-async-windows activate)
(save-window-excursion
ad-do-it))
Sadly there is no good way to avoid this buffer as it's called directly by 'shell-command' function ('async-shell-command' is just a wrapper).
So, a much better way is to replace 'async-shell-command' with 'start-process'.
You should start process with 'set-process-sentinel' to detect the moment when process emits 'exit signal. Then kill process.
A slightly more complicated incantation should get you what you want. Just use a shell command like: (okular ? >& /dev/null &).
I haven't tested this with okular, but I can do M-! ((echo foo; sleep 10; echo bar) >& /dev/null &) and Emacs returns immediately without creating a new buffer.
I solved the problem, using this method:
;list of programs, corresponding to extensions
(setq alist-programs
'(("pdf" ."okular")
("djvu" . "okular")
("mp3" . "xmms")))
(defun my-run-async-command (command file)
"Run a command COMMAND on the file asynchronously.
No buffers are created"
(interactive
(let ((file (car (dired-get-marked-files t current-prefix-arg))))
(list
;last element of alist-programs, contains COMMAND
(cdr
(assoc
(file-name-extension file)
alist-programs))
file)))
;begin of function body
(if command ;command if not nil?
(start-process "command" nil command file)
)
)
;attach function to <f2> key
(add-hook 'dired-mode-hook
(lambda ()
(define-key dired-mode-map (kbd "<f2>") 'my-run-async-command)))
The suggestions to use start-process are ok if he is running a distinct program on the path of course. But if you want run some shell command in a specific directory (eg your project directory) then simply quell the popup - you frequently want the buffer but just dont want it jumping up in your face. eg I run a webserver and I want to see the output, just not now...
(use-package php-mode
:config
(add-to-list 'display-buffer-alist
(cons "\\*Symfony Web Server\\*.*" (cons #'display-buffer-no-window nil)))
(defun php-mode-webserver-hook ()
(if (projectile-project-root) (let ((default-directory (projectile-project-root)))
(unless (get-buffer "*Symfony Web Server*" )
(async-shell-command "bin/console server:run" "*Symfony Web Server*")))))
:hook (php-mode . php-mode-webserver-hook))
Within emacs, I want to have multiple shells open, type a command once, and have it run in each shell -- similar to the way multixterm ( http://freecode.com/projects/multixterm ) does.
With some minimal testing, this will do:
(defun send-to-all-shells ()
(interactive)
(let ((command (read-from-minibuffer "Command: ")))
(mapcar #'(lambda (x) (comint-send-string x (concat "\n" command "\n")))
(remove-if-not
#'(lambda (x)
(string= "/bin/bash"
(car (process-command x))))
(process-list)))))
To run, just M-x send-to-all-shells, enter the command you want, and it will be sent to all open shells. This assumes your shell is found in /bin/bash. If not, change that bit accordingly.
If you do this a lot, you'll want to bind that to your favourite key combo. It would be possible to borrow and modify the code in comint-send-input such that you could just enter the command you want at the prompt of one shell, hit your key and have that command send to all shells simultaneously. I'm short on time, so I'll leave that as an exercise for the reader.