emacs shell could not process % character - shell

in emacs shell, when I type command "echo %", emacs will dead, when i cancel the command, the Message show error below:
comint-simple-send-around: Format string ends in middle of format specifier
I debug the error, because Emacs use format function, %% could work for %, but still send shell with %% character.
and below is the definition:
(defun comint-simple-send-around (simle-function proc string)
(dolist (item name-variable-map)
(let ((name (car item))
(value (symbol-value (cdr item))))
(setq string (replace-regexp-in-string name value string))
))
(message string)
(funcall simle-function proc string)
)
(advice-add #'comint-simple-send :around #'comint-simple-send-around)

The bug is in your custom code, where you're doing this:
(message string)
Where string is obviously evaluating to an invalid format string.
(message FORMAT-STRING &rest ARGS)
...
The first argument is a format control string, and the rest are data
to be formatted under control of the string. Percent sign (%), grave
accent (`) and apostrophe (') are special in the format; see
`format-message' for details. To display STRING without special
treatment, use (message "%s" STRING).

Related

Getting the output of a process

I am trying to create a function which takes as input a path and returns the output of the ls terminal command as a string. I'm using a process and sentinel since I'll eventually want to create other functions which will take some time to execute, and I want them to run asynchronously.
(defun ls-to-string (path)
(let (ls-proc
ls-output)
(progn (setq ls-proc (start-process "" "ls-buffer" "ls" path))
(set-process-sentinel ls-proc (lambda (p e)
(if (string= e "finished\n")
(progn (set-buffer "ls-buffer")
(setq ls-output (buffer-string))
(kill-buffer "ls-buffer")
(message ls-output))))) <---- (1)
ls-output))) <---- (2)
(ls-to-string "/home")
I have (temporarily) added (message ls-output) just to show that ls-output does contain the string (1). However the return value is nil (2).

Elisp function to replace underscores for white spaces in the current line

I'm trying to write a very simple function to replace all the underscores in the current line for whites paces.
This is what I have so far
(select-current-line)
(exit-minibuffer)
(query-replace "_" " " nil (if (and transient-mark-mode mark-active) (region-beginning)) (if (and transient-mark-mode mark-active) (region-end)))
But I get the following message:
No catch for tag: exit, nil
I'm not very convinced that using query-replace in an active selection is the best way, but I am not a elisp programmer at all.
Any ideas?
Thanks
UPDATE:
Based in the answers below, this is the piece code that I ended using:
(let ((end (copy-marker (line-end-position))))
(while (re-search-forward "_" end t)
(replace-match " " nil nil)))
C-h f query-replace RET doesn't say what I wanted to quote, but C-h f perform-replace RET does:
Don't use this in your own program unless you want to query and set the mark
just as `query-replace' does. Instead, write a simple loop like this:
(while (re-search-forward \"foo[ \\t]+bar\" nil t)
(replace-match \"foobar\" nil nil))
As for limiting it to the current line, the best way to do it is to use the second arg of re-search-forward:
(let ((end (copy-marker (line-end-position))))
(while (re-search-forward \"foo[ \\t]+bar\" end t)
(replace-match \"foobar\" nil nil)))
Notice the use of copy-marker because the position of the end-of-line will keep changing as you modify the line, so you don't want to keep the position as a plain integer but as a marker (which is tied to a place in the text).
A common alternative is to go backwards (since insertion/deletions only affect positions after the change):
(end-of-line)
(let ((beg (line-beginning-position)))
(while (re-search-backward \"foo[ \\t]+bar\" beg t)
(replace-match \"foobar\" nil nil)))

Using syntax-table information in elisp for tokenization

I would like to use elisp to tokenize the following:
variable := "The symbol \" delimits strings"; (* Comments go here *)
as:
<variable> <:=> <The symbol \" delimits strings> <;>
based on the information from the buffer's syntax-table.
I have the symbol-table setup appropriately and am currently using the following function which operates correctly except for the string constant (either returns token or nil if point is not at an identifier or one of the operators in the regex).
(defun forward-token ()
(forward-comment (point-max))
(cond
((looking-at (regexp-opt '("=" ":=" "," ";")))
(goto-char (match-end 0))
(match-string-no-properties 0))
(t (buffer-substring-no-properties
(point)
(progn (skip-syntax-forward "w_")
(point))))))
I am an elisp novice, so any pointers are appreciated.
I don't think your skip-syntax-forward use is correct for strings.
I think you need to add a cond clause like this:
((looking-at "\"")
(let* ((here (point)) (there (scan-sexps here 1)))
(goto-char there)
(buffer-substring-no-properties
(1+ here) (1- there))))
to handle string literals.

Can I read the Windows Registry from within elisp? How?

I just wanna do something like this
(defun my-fun (reg-path)
"reads the value from the given Windows registry path."
...??...
)
is there a built-in fn that does this?
or is there a command-line tool builtin to windows that I can run to retrieve a reg value?
The way I am imagining doing it, is to run a .js file in cscript.exe that does the work.
ANSWER
(defun my-reg-read (regpath)
"read a path in the Windows registry. This probably works for string
values only. If the path does not exist, it returns nil. "
(let ((reg.exe (concat (getenv "windir") "\\system32\\reg.exe"))
tokens last-token)
(setq reg-value (shell-command-to-string (concat reg.exe " query " regpath))
tokens (split-string reg-value nil t)
last-token (nth (1- (length tokens)) tokens))
(and (not (string= last-token "value.")) last-token)))
==> Thank you to Oleg.
Use reg command line utility.
Emacs command
(shell-command "REG QUERY KeyName" &optional OUTPUT-BUFFER ERROR-BUFFER)
allows you to run a shell command. The output is sent to the OUTPUT-BUFFER.
Here's what I did:
(defun my-reg-read (regpath)
"read a path in the Windows registry"
(let ((temp-f (make-temp-file "regread_" nil ".js"))
(js-code "var WSHShell, value, regpath = '';try{ if (WScript.Arguments.length > 0){regpath = WScript.Arguments(0); WSHShell = WScript.CreateObject('WScript.Shell'); value = WSHShell.RegRead(regpath); WScript.Echo(value); }}catch (e1){ WScript.Echo('error reading registry: ' + e1);}")
reg-value)
(with-temp-file temp-f (insert js-code))
(setq reg-value (shell-command-to-string (concat temp-f " " regpath)))
(delete-file temp-f)
reg-value ))
The elisp function creates a temporary file, then writes a bit of javascript logic into it. the javascript reads the windows registry for a given path. The elisp fn then runs the temporary file, passing the registry path to read. It deletes the file, then returns the result of running it.

How to wait for / capture aysnchronous shell command output in emacs lisp?

If I execute a shell command asynchronously in emacs lisp like so:
(shell-command "mycommand &")
Is there a way to wait for the command to generate output before continuing? For my current application, it is probably sufficient to wait until the command generates any output at all, but ideally I'd like to capture the output for additional processing. Is this possible?
You should use comint-output-filter-functions variable that contains function to call after output is inserted into the buffer.
For example, you can do :
(add-hook 'comint-output-filter-functions '(lambda (txt) (message "hello")))
N.B. : From Emacs 23.2, you have the new command async-shell-command, bound globally to M-&.
This executes your command asynchronously without requiring an ampersand. The output of your command is sent to the buffer
*Async Shell Command*.
Perhaps you need to register a Process Filter to give you the callback timing you need? See 37.9 Receiving Output from Processes in the Elisp manual (I see this in my copy for Emacs 22.3).
Here is an example of running a callback when you get the first process output and also storing it into an "associated buffer". Copy it to your *scratch* buffer and eval-region it, but make sure to split-window and show the *Messages* buffer visible so that you can see what's going on.
;; this is emacs lisp (and a comment line)
(defvar my-callback-got-some-already nil)
(defun my-callback ()
(message "callback ran at %s" (current-time-string)))
(defun my-filter-waits-for-first-time-input (proc string)
(unless my-callback-got-some-already
(setq my-callback-got-some-already t)
;; do your one-time thing
(my-callback))
;; insert into the associated buffer as if no process filter was
;; registered
(with-current-buffer (process-buffer proc)
(let ((moving (= (point) (process-mark proc))))
(save-excursion
;; Insert the text, advancing the process marker.
(goto-char (process-mark proc))
(insert string)
(set-marker (process-mark proc) (point)))
(if moving (goto-char (process-mark proc))))))
(defun async-callback-test-harness ()
(interactive)
(let ((process-handle "async-callback-test")
(associated-process-buffer "*async-callback-test*")
(command "ls")
(busy-loop-var ""))
(setq my-callback-got-some-already nil)
(message "start test %s" (current-time-string))
(start-process process-handle associated-process-buffer command)
;; Supposedly async but Emacs doesn't get the input until
;; "Emacs is waiting" so the following set-process-filter
;; can be registered in time.
;; To prove the point, make emacs busy loop to show that the
;; emacs doesn't drop its input and
;; the callback will get the unskipped input.
(switch-to-buffer associated-process-buffer)
(dotimes (k 2000) ; about two seconds on my machine
(setq busy-loop-var (concat busy-loop-var "busy looping...")))
(message "done busy waiting %s" (current-time-string))
(set-process-filter (get-process process-handle)
'my-filter-waits-for-first-time-input)
nil))
;; run it!
(async-callback-test-harness)

Resources