How to pass current-prefix-arg to this-command - search

I want to reuse current-prefix-arg when calling this-command. I can imagine ways of capturing its value and passing it to modified functions. But, this doesn't seem like a great solution. How can I reuse it (eg. push it back onto a sort of call stack, or whatever emacs uses)?
The example is a simple function to increment/decrement numbers in region I was just writing where I want to temporarily bind i to increment or decrement if it was called with prefix. Can I do this without adding another argument to the function, but just using the original prefix?
(defun my-toggle-increment-numbers (start end)
"Simple function to increment numbers in region. Decrement with prefix."
(interactive "r")
(let (deactivate-mark)
(goto-char start)
(while (re-search-forward "\\([[:digit:]]+\\)" end 'move)
(replace-match (number-to-string
(+ (if current-prefix-arg -1 1)
(string-to-number (match-string 1))))
nil nil nil 1))
;; what is good way to reused the current-prefix-argument value when
;; calling this-command?
(set-transient-map
(let ((km (make-sparse-keymap)))
(define-key km "i" this-command)
km)
t)))

Try this:
(defun my-toggle-increment-numbers (start end &optional decrement)
"Simple function to increment numbers in region. Decrement with prefix."
(interactive "r\nP")
(let (deactivate-mark)
(setq start (copy-marker start)
end (copy-marker end))
(goto-char start)
(while (re-search-forward "\\([-]?[[:digit:]]+\\)" end 'move)
(replace-match (number-to-string (+ (if decrement -1 1)
(string-to-number (match-string 1))))
nil nil nil 1))
(set-transient-map
(let ((km (make-sparse-keymap)))
(define-key km "i" `(lambda ()
(interactive)
(my-toggle-increment-numbers ',start ',end ',decrement)))
km)
t)))
You forgot to include the minus sign preceding your [[:digit:]].
You need to either use lexical binding or construct a command that binds the current values of start, end and current-prefix-arg (or decrement - see next).
It's a bit simpler if you use an argument instead of current-prefix-arg.
(You ask if you can just use current-prefix-arg instead of adding an arg for it. Yes. In that case, let-bind current-prefix-arg in the constructed command that gets invoked for subsequent calls.)
Since replacement can change the number of digits in a numeral (e.g. from 9 to 10, you need to use a marker instead of the number value of end in subsequent calls.

I think the cleanest way is to create a command which calls this-command passing it the prefix arg:
;; This relies on -*- lexical-binding:t -*-
(defun my-toggle-increment-numbers (start end)
[...]
(set-transient-map
(let ((km (make-sparse-keymap))
(tc this-command)
(cpa current-prefix-arg))
(define-key km "i"
(lambda () (interactive)
(let ((current-prefix-arg cpa))
(call-interactively tc))))
km)
t)))
It's probably more verbose than what you were imagining, but I think it's the closest there is to what you're asking. A simpler way to get almost the same result could be:
(defun my-toggle-increment-numbers (start end)
[...]
(setq prefix-arg current-prefix-arg)
(set-transient-map
(let ((km (make-sparse-keymap)))
(define-key km "i" this-command)
km)
t)))

Related

emacs: search and replace on a region

So, I have this excellent function (that someone made for me) for doing multiple search and replaces on an entire buffer.
(defun accent-replace-whole-buffer ()
"Corrects macrons from badly scanned latin"
(interactive "*")
(dolist (ele (list ?â ?ä ?ê ?ë ?î ?ô ?ü ?ï))
(setq elt (char-to-string ele))
(goto-char (point-min))
(while (search-forward elt nil t 1)
(replace-match
(char-to-string
(pcase ele
(`?â ?ā)
(`?ä ?ā)
(`?ê ?ē)
(`?ë ?ē)
(`?î ?ī)
(`?ô ?ō)
(`?ü ?ū)
(`?ï ?ī)))))))
and I would like to make another function, which does this, only on the selected region.
How would I go about this? Is there a nice tutorial anywhere?
Use narrow-to-region, inside save-restriction:
(defun accent-replace-in-region (begin end)
"Corrects macrons in active region from badly scanned latin"
(interactive "*r")
(save-restriction
(narrow-to-region begin end)
(dolist (ele (list ?ā ?ā ?ē ?ē ?ī ?ō ?ū ?ī))
(setq elt (char-to-string ele))
(goto-char (point-min))
(while (search-forward elt nil t 1)
(replace-match
(char-to-string
(pcase ele
(`?â ?ā)
(`?ä ?ā)
(`?ê ?ē)
(`?ë ?ē)
(`?î ?ī)
(`?ô ?ō)
(`?ü ?ū)
(`?ï ?ī))))))))
Instead of the builtin interactive code "r", using that form:
(defun MYFUNTION (&optional beg end)
(interactive "*")
(let ((beg (cond (beg)
((use-region-p)
(region-beginning))
(t (point-min))))
(end (cond (end (point-marker end))
((use-region-p)
(point-marker (region-end)))
(t (point-marker (point-max))))))
(and beg end (narrow-to-region beg end))
(goto-char beg)
;; here some replace example revealing the problem mentioned
(while (re-search-forward "." end t 1)
(replace-match "+++++++++"))))
Basically two reasons for this: Make sure, the region is visible when acting upon. "r" doesn't care for transient-mark-mode. Unfortunately use-region-p also has some quirks. Second reason: end needs to be updated when a replacing will change the length of the region.

Invalid function in Emacs Lisp

I'm creating a function in Emacs Lisp that will read that whole buffer aloud if there is no active region. Otherwise, it reads the active region.
(defun speak-my-text () "Speaks text in buffer."
(interactive)
(if (equal mark-active t)
(
(kill-ring-save (point-min) (point-max))
(start-process-shell-command "speakbuffvar" nil
"bash -c \"killall espeak;xsel --clipboard|espeak -s 290\"")
)
(
(kill-ring-save (region-beginning) (region-end))
(start-process-shell-command "speakbuffvar" nil
"bash -c \"killall espeak;xsel --clipboard|espeak -s 290\"")
)))
(global-set-key (kbd "C-z") 'speak-my-text)
I'm having trouble with the first line of the else clause:
(kill-ring-save (region-beginning) (region-end))
When I define the function, bind it, and run, I get "Invalid function" and it points to that line. I'm running Linux Mint.
Use C-h f progn to evaluate multiple expressions sequentially.
You're currently attempting to call a function named (kill-ring-save (region-beginning) (region-end)) and pass it the argument (start-process-shell-command ...)
Naturally, Emacs is telling you that (kill-ring-save (region-beginning) (region-end)) is not the name of a function.
In addition to phils' answer:
mark-active is not reliable in this context, as it might be
non-nil also if a region has no extend.
Function region-active-p would be usable, however depends on an
active transient-mark-mode, which might be unrelated - in most
cases it's useful and sufficient BTW.
Here is a example how to check for an valid region greater then
zero and surpassing transient-mark-mode issue:
(defun ar-region-active-p ()
"Check for and existing region of some extend.
Don't mix up that question with transient-mark-mode "
(interactive)
(and (ignore-errors (region-beginning))(region-end) (< (region-beginning)(region-end))))
Based on this, your command might be written slightly differently:
(defun my-command-on-region ()
"If a region of some extend exists, use on it.
Otherwise use whole buffer.
Doesn't require `transient-mark-mode' being active"
(interactive)
(let ((beg (or (and (ignore-errors (region-beginning))(region-end) (< (region-beginning)(region-end))(region-beginning))
(point-min)))
(end (or (and (ignore-errors (region-beginning))(region-end) (< (region-beginning)(region-end))(region-end))
(point-max))))
(DO-SOMETHING beg end)))

Emacs Lisp search-backward

Preamble
Using VTK library with C++, quite often I have to write something like this:
vtkInteractorStyleRubberBandZoom *isrbz = vtkInteractorStyleRubberBandZoom::New();
Furthermore, every time I need to use a new VTK class in my program, I have to go somewhere up the source file and add #include "vtkInteractorStyleRubberBandZoom.h"
How do I automate it, so I have to type each of the excruciatingly long class names one time instead of three?
I tried writing an Emacs minor mode for it. There are probably existing solutions out there already (YaSnippet?), but I thought that writing it myself would be a good excercise, too.
Code
;vtk-mode.el
;add to .emacs:
;(load "vtk-mode")
;(global-set-key [(control =)] 'expand-vtk)
(defun expand-vtk ()
(interactive)
(setq now (point))
(setq vtkstart (search-backward "vtk"))
(setq vtkend (- (search-forward " ") 1))
(setq vtkname (buffer-substring vtkstart vtkend))
;check for #include "vtkBlah.h"
(setq includename (format "#include \"%s.h\"\n" vtkname))
(search-backward includename nil (append-include-vtk includename))
(goto-char (+ now (length includename)))
(insert (format "= %s::New();" vtkname)))
(defun append-include-vtk (incname)
(goto-char 0)
(insert incname))
Problem
Basically, it works, except that searching for an include name always fails, e. g.:
vtkSomething *smth /*press C-= here, it looks backward for
#include "vtkSomething.h", can't find it and
calls append-include-vtk, adding it to the beginning
of the file, then comes back here and expands this line into: */
vtkSomething *smth = vtkSomething::New();
//and let's add another instance of vtkSomething...
vtkSomething *smth2 /*press C-= again, it looks backward for
#include "vtkSomething", and fails, despite the fact
that it was added by the previous command. So it adds it again."*/
What am I doing wrong here with search-backward?
(there's another (at least one) bug in the code, I shouldn't add the (length includename) if the search-backward for it was successful, but for now I am more interested in how to make it successful, in the first place)
OK, I got it. Somehow I got an idea that the third argument of search-backward (noerror) is a callback, which it isn't. Therefore it is evaluated every time, not just when the search fails. It should be something like this instead:
(defun expand-vtk ()
(interactive)
(setq now (point))
(setq vtkstart (search-backward "vtk"))
(setq vtkend (- (search-forward " ") 1))
(setq vtkname (buffer-substring vtkstart vtkend))
;check for #include "vtkBlah.h"
(setq includename (format "#include \"%s.h\"\n" vtkname))
(if (search-backward includename nil t)
(goto-char now)
(progn (append-include-vtk includename)
(goto-char (+ now (length includename)))))
(insert (format "= %s::New();" vtkname)))
(defun append-include-vtk (incname)
(goto-char 0)
(insert incname))
A command that's built into Emacs and will help you avoid typing excruciatingly long class names is dabbrev-expand (bound to M-/):
(dabbrev-expand ARG)
Expand previous word "dynamically".
Expands to the most recent, preceding word for which this is a prefix.
If no suitable preceding word is found, words following point are
considered. If still no suitable word is found, then look in the
buffers accepted by the function pointed out by variable
`dabbrev-friend-buffer-function'.
Having typed vtkInteractorStyleRubberBandZoom once, the next time you need it you just type vtkI M-/.

Searching with intelligent bracket counting (Elisp)

I have the following function that deletes the LaTeX command surrounding the current cursor position:
(defun remove-tex-cmd ()
(interactive)
(save-excursion
(let (cur-point beg-point end-point)
(setq cur-point (point))
(catch 'notexcmd
(if (not (re-search-backward "\\.*?{" nil t)) ; now the point is at the {
(throw 'notexcmd nil))
(search-backward "\\" nil t)
(setq beg-point (point))
(re-search-forward "}")
(setq end-point (point))
(if (> end-point cur-point)
(kill-region beg-point end-point))
(throw 'notexcmd nil)))
(if 'notexcmd
(message "no tex command at point"))))
It works well except for the following situation, because it simply matches the next closing }:
\test{a<cursor here>sdf ${bla}+1$}
results in
+1$}
I could, of course, count the opening and closing brackets. However, as this problem should occur frequently, I wonder whether there exists some more intelligent search function, or am I missing a totally different point?
Use list- or sexp- based operations:
(defun remove-tex-cmd ()
(interactive)
(backward-up-list 1)
(backward-sexp 1)
(kill-sexp 2))
To handle scan error when outside parentheses:
(defun remove-tex-cmd ()
(interactive)
(condition-case nil
(progn
(backward-up-list 1)
(backward-sexp 1)
(kill-sexp 2))
(scan-error (message "Outside parentheses."))))

Simplest example of backwards continuations in Scheme without explicit mutation

I've written a small Scheme interpreter in C#, and realised that the way I had implemented it, it was very easy to add support for proper continuations.
So I added them... but want to "prove" that they way that I've added them is correct.
My Scheme interpreter however has no support for "mutating" state - everything is immutable.
So it was pretty easy to write a unit test to expose "upwards" continuations:
AssertEqual(Eval("(call/cc (lambda (k) (+ 56 (k 3))))"), 3);
However, I also want to write a unit test that demonstrates that if the continuation "escapes" then that still works too:
AssertEqual(Eval("(call/cc (lambda (k) k))", <some continuation>);
But of course, the above would just test that "I got a continuation"... not that it's actually a valid continuation.
All of the examples I can find, however, always end up using "set!" to demonstrate the escaped continuation.
What's the simplest Scheme example that demonstrates proper support for backwards continuations without relying on mutation?
Are backwards continuations any use without mutation? I am beginning to suspect that they are not, because you could only use it to execute the exact same calculation again... which is meaningless if there are no side-effects. Is this why Haskell does not have continuations?
I don't know if this is the simplest, but here's an example of using backwards continuations without any call to set! or similar:
(apply
(lambda (k i) (if (> i 5) i (k (list k (* 2 i)))))
(call/cc (lambda (k) (list k 1))))
This should evaluate to 8.
Slightly more interesting is:
(apply
(lambda (k i n) (if (= i 0) n (k (list k (- i 1) (* i n)))))
(call/cc (lambda (k) (list k 6 1))))
which computes 6! (that is, it should evaluate to 720).
You can even do the same thing with let*:
(let* ((ka (call/cc (lambda (k) `(,k 1)))) (k (car ka)) (a (cadr ka)))
(if (< a 5) (k `(,k ,(* 2 a))) a))
(Man, stackoverflow's syntax highlighting fails massively on scheme.)
I think you're right -- without mutation, backwards continuations do nothing that forward continuations can't.
Here's the best I've come up with:
AssertEqual(Eval("((call/cc (lambda (k) k)) (lambda (x) 5))", 5);
Not amazing, but it is a backwards continuation which I then "call" with the actual function I wish to invoke, a function that returns the number 5.
Ah and I've also come up with this as a good unit test case:
AssertEqual(Eval("((call/cc call/cc) (lambda (x) 5))", 5);
I agree with Jacob B - I don't think it's that useful without mutable state... but would be still be interested in a counter-example.
Functional Threads:
You can use a recursive loop to update state without mutation. including the state of the next continuation to be called. Now this is more complicated than the other examples given, but all you really need is the thread-1 and main loop. The other thread and "update" function are there to show that continuations can be used for more than a trivial example. Additionally, for this example to work you need an implementation with the named let. This can be translated into an equivalent form made with define statements.
Example:
(let* ((update (lambda (data) data)) ;is identity to keep simple for example
(thread-1
(lambda (cc) ;cc is the calling continuation
(let loop ((cc cc)(state 0))
(printf "--doing stuff state:~A~N" state)
(loop (call/cc cc)(+ state 1))))) ;this is where the exit hapens
(thread-2
(lambda (data) ;returns the procedure to be used as
(lambda (cc) ;thread with data bound
(let loop ((cc cc)(data data)(state 0))
(printf "--doing other stuff state:~A~N" state)
(loop (call/cc cc)(update data)(+ state 1)))))))
(let main ((cur thread-1)(idle (thread-2 '()))(state 0))
(printf "doing main stuff state:~A~N" state)
(if (< state 6)
(main (call/cc idle) cur (+ state 1)))))
Which outputs
doing main stuff state:0
--doing other stuff state:0
doing main stuff state:1
--doing stuff state:0
doing main stuff state:2
--doing other stuff state:1
doing main stuff state:3
--doing stuff state:1
doing main stuff state:4
--doing other stuff state:2
doing main stuff state:5
--doing stuff state:2
doing main stuff state:6

Resources