Why is "goto-line" in Emacs for interactive use only? - emacs

What problem can happen if the goto-line function is used in a non-interactive elisp program? Its docstring gives a warning saying that:
This function is usually the wrong thing to use in a Lisp program.
What you probably want instead is something like:
(goto-char (point-min)) (forward-line (1- N))
Moreover, when I try to byte-compile-file my init file including goto-line, I get a unpleasant warning like this once again:
.emacs:170:19:Warning: `goto-line' used from Lisp code
That command is designed for interactive use only
Is using goto-line in a non-interactive program really so dangerous? Relatedly, why is the suggested forward-line solution preferable?

Firstly, this prevents Elisp programmers from fall into bad habits -- writing
inefficient code in a line-number centric way. i.e. instead of using
(forward-line 1) calculating the current line number, incrementing, and using
goto-line.
From this mailing list article:
In a nutshell, the reason why goto-line should not be a frequently
used command is that normally there's no reason to want to get to line
number N unless you have a program that told you there's something
interesting on that line.
Secondly, goto-line manipulates the user's environment in addition to moving
the point (i.e. push-mark). For non-interactive use, this may not be what
you want. On the other hand if having considered all this, you believe
goto-line is exactly what you need, then just call it like this:
(defun foo ()
(interactive)
(with-no-warnings
(goto-line N)))
And you won't get any compiler warnings.

in addition to what was said:
"goto-line" finally recurs onto "(forward-line (1- line)", which in effect does the work. All other of the 43 lines of "goto-line" command body deal with interactive use. For example considering a possibly universal argument.
When writing a program resp. when running it, your computer is in another state than following an interactive call. Thus you should address this state by using "forward-line" straight on.

Related

indent-[code-]rigidly called from emacs LISP function

I'm trying to write an emacs LISP function to un-indent the region
(rigidly). I can pass prefix arguments to indent-code-rigidly or
indent-rigidly or indent-region and they all work fine, but I don't
want to always have to pass a negative prefix argument to shift things
left.
My current code is as below but it seems to do nothing:
(defun undent ()
"un-indent rigidly."
(interactive)
(list
(setq fline (line-number-at-pos (region-beginning)))
(setq lline (line-number-at-pos (region-end)))
(setq curIndent (current-indentation))
;;(indent-rigidly fline lline (- curIndent 1))
(indent-region fline lline 2)
;;(message "%d %d" curIndent (- curIndent 1))
)
)
I gather that (current-indentation) won't get me the indentation of the first line
of the region, but of the first line following the region (so a second quesiton is
how to get that!). But even when I just use a constant for the column (as shown,
I don't see this function do any change.
Though if I uncomment the (message) call, it displays reasonable numbers.
GNU Emacs 24.3.1, on Ubuntu. And in case it matters, I use
(setq-default indent-tabs-mode nil) and (cua-mode).
I must be missing something obvious... ?
All of what Tim X said is true, but if you just need something that works, or an example to show you what direction to take your own code, I think you're looking for something like this:
(defun unindent-rigidly (start end arg &optional interactive)
"As `indent-rigidly', but reversed."
(interactive "r\np\np")
(indent-rigidly start end (- arg) interactive))
All this does is call indent-rigidly with an appropriately transformed prefix argument. If you call this with a prefix argument n, it will act as if you had called indent-rigidly with the argument -n. If you omit the prefix argument, it will behave as if you called indent-rigidly with the argument -1 (instead of going into indent-rigidly's interactive mode).
There are a number of problems with your function, including some vary
fundamental elisp requirements. Highly recommend reading the Emacs Lisp
Reference Manual (bundled with emacs). If you are new to programming and lisp,
you may also find An Introduction to Emacs Lisp useful (also bundled with
Emacs).
A few things to read about which will probably help
Read the section on the command loop from the elisp reference. In particular,
look at the node which describes how to define a new command and the use of
'interactive', which you will need if you want to bind your function to a key
or call it with M-x.
Read the section on variables from the lisp reference
and understand variable scope (local v global). Look at using 'let' rather
than 'setq' and what the difference is.
Read the section on 'positions' in the elisp reference. In particular, look at
'save-excursion' and 'save-restriction'. Understanding how to define and use
the region is also important.
It isn't clear if your writing this function just as a learning exercise or
not. However, just in case you are doing it because it is something you need to
do rather than just something to learn elisp, be sure to go through the Emacs
manual and index. What you appear to need is a common and fairly well supported
requirement. It can get a little complicated if programming modes are involved
(as opposed to plain text). However, with emacs, if what you need seems like
something which would be a common requirement, you can be fairly confident it is
already there - you just need to find it (which can be a challenge at first).
A common convention is for functions/commands to be defined which act 'in
reverse' when supplied with a negative or universal argument. Any command which
has this ability can also be called as a function in elisp code with the
argument necessary to get that behaviour, so understanding the inter-play
between commands, functions and calling conventions is important.

How to toggle between indentations on emacs?

emacs n00b here.
I face this problem at least once a week, I have a function call with its arguments one per line, but I'd like to reformat that such that all the arguments go to one line, i.e. I want to go from:
f(
x,
y,
z
);
to:
f(x, y, z);
what's the best way to do that?
In general, a simple approach to custom reformatting requirements is to create a keyboard macro which does the required editing in a generic way.
Abilities like moving across sexps & balanced expressions, searching and replacing within regions, and narrowing and widening the buffer all make this sort of thing pretty straightforward.
You can then give the macro a name, output its definition into your init file, and bind it to a key for future usage, all with no elisp knowledge required.
C-hig (emacs) Keyboard Macros RET
Edit: (for "Emacs n00bs" everywhere).
DO learn how to use keyboard macros. The learning curve is pretty shallow1, and they will pay amazing dividends in the long term.
Once you've learned how they work, force yourself to use them: Whenever you encounter a problem, say to yourself "Can I do this with a keyboard macro?" and if you think the answer is yes, then give it a try.
If you don't make yourself use them to begin with, you probably won't often think about them when use-cases crop up; but once they're a familiar part of your tool kit you'll find yourself using them very regularly.
1 Shallow, but probably longer than you expect, as you gradually come to realise just how much you can actually accomplish with the things. My own moment of clarity came when it occurred to me that I wasn't restricted to a single buffer, and correlating/extracting/transforming data from multiple buffers was something I could automate easily.
And of course macros can do anything that you can do, so their power grows with your own knowledge of Emacs.
Well, I doubt that it is the best way to do it but I wrote a function anyways. So here it goes:
(defun format-args-column-to-inline()
"Takes a c-style function whose arguments listed one per line and puts them inline."
(interactive)
(beginning-of-line 1)
(re-search-forward "(")
(forward-char -1)
(let ((start (point)))
(save-restriction
(save-excursion
(forward-sexp 1)
(narrow-to-region start (point)))
(while (re-search-forward "$")
(progn
(delete-forward-char 1)
(just-one-space 1))))))
Put your cursor somewhere in the first line and call the function.
Edit: Just saw that you wanted something slightly different. The output of this function is f( x, y, z ); [note the trailing and leading space of the argument list].

Emacs: define custom hook on a command

Is there a way to hook onto command A, so that B is always called after A executes?
I think the most straight-forward way to accomplish this is through the use of advice.
You would do something along the lines of:
(defadvice command-A (after b-after-a activate)
"Call command-B after command-A"
(command-B))
This approach has the advantage that it works even when command-A is redefined. It does not, however, work on macros or on primitive functions called from the C code. But, in practice the thought of advising those functions is rare.
That said, it might be worth looking into just defining a new command (command-C) which first calls command-A and then command-B.
You could also play around with symbol function indirection and writing a new command.
It kind of depends on what you're trying to solve.
You can advice a function using defadvice:
;; This is the original function command-A
(defun command-A () (do-it))
;; This call will cause (do-sometihng-after-command-A) to be called
;; every-time (command-A) is called.
(defadvice command-A (after after-command-A)
(do-something-after-command-A))
;; Enable the advice defined above
(ad-activate 'command-A)
See the info node (elisp)Advising Functions for more information and examples.

Emacs Macro to Start in Shell Mode and Run a Command

I have a confession: I don't know Lisp. Despite that fact, with a bit of help from some co-workers, I managed to write an emacs macro/script which:
switched to shell mode (ie. M-x shell-mode)
disabled truncating lines (ie. M-x toggle-truncate-lines)
started a database console (ie. "mysql")
I was then able to start emacs with that macro using the --script option, and suddenly I had a way to start mysql in a much friendlier environment with a single command :-)
But here's the problem: I changed jobs and left that script behind. Now I'd very much like to re-create that script at my new job, but I no longer have any emacs experts to help me write it like I did at the old job.
Now, I really hate SO posts where someone basically says "please write my code for me", so I don't want to do that. However, if any emacs macro experts could at least give me some pointers (like "here's how you invoke a M-x command in a macro"), or point me to an emacs-macro-writing guide, or otherwise "teach me to fish" on this issue, I would greatly appreciate it.
... and if someone just happened to have a similar script already lying around that they wanted to post, I certainly wouldn't complain ;-)
Most emacs commands (i.e., M-x toggle-truncate-lines) can be translated directly to elisp by wrapping them in parentheses:
(toggle-truncate-lines)
The rumours are true, in lisp you just scatter parentheses around and they make magic.
Now in this case, you can do better. Toggling makes sense for an interactive function, but in a program you don't really want to toggle truncate-lines, you want to turn on truncate-lines. Its the same thing if truncate-lines was turned off to begin with, but you don't know when your program will be run next. Anyways, in Emacs, features are often controlled by a variable. In this case, the variable is truncate-lines, and to turn that feature on, you set the variable to t (which means true).
To do this, use:
(setq truncate-lines t)
We use setq instead of = for assignment, because they made lisp before = had been invented.
For the real scoop you should take a look at Robert Chassel's excellent "An introduction to to Programming in Emacs Lisp". It comes built-in with your emacs, you can get to it with C-h i m Emacs Lisp Intro.
A good way (I think) to start writing elisp functions is to record keyboard macros, and then to analyse them using edit-kbd-macro
For example, if you start recording a keyboard macro using f3, then do interactively all the things you want and terminate the macro using f4, you can see the underlying emacs-lisp commands using M-xedit-kbd-macrof4 (this last f4 is the key binding you'd have used to execute the keyboard macro)
<<shell>> ;; shell
<<toggle-truncate-lines>> ;; toggle-truncate-lines
mysql ;; self-insert-command * 5
RET ;; comint-send-input
Now you can write a script using these functions, looking up the documentation (e.g. C-h ftoggle-truncate-lines) to see if you should call them with special arguments in non-interactive mode.
You should also replace self-insert-command by calls to insert.
This should give you something like the following script, which you can call using emacs --load myscript.el
(shell)
(toggle-truncate-lines 1)
(insert "mysql")
(comint-send-input)
Of course, this might not work as expected the first time, so you might have to eval (setq debug-on-error t) to get debugging information.
What version of Emacs are you using?
In Emacs 24, I have M-x sql-mysql, which does everything you ask and has font-locking.

how to write scheme program fast in emacs

(define (cube guess x)
(if (good-enough? guess x)
guess
(improve guess x)))
I'm using emacs+Racket, but when I write in Racket,it doesn't auto-complete.
I also can't write the Anti-brackets in the same line,like this
(define (cube guess x) ). I want to use the 'return' key to make the anti-brackets next line, however the scheme interpreter will compute the expression,then it will be wrong.
then if we write the code in the scheme-mode buffer,it may be some bother, we have to
select the region,then compute in another buffer
Anyone tell me some better ways? sorry for my poor English!
It looks to me like you're using an interactive interpreter, and when you hit the "return" key in the middle of a line, it sends the expression to be evaluated rather than allowing you to edit it further. Is this correct? If so, I would encourage you to take a look at Neil Van Dyke's "Quack" package, which (IIRC) is designed to allow you to edit Racket code using emacs.
If you're not married to emacs, then of course I would also suggest trying to use DrRacket.
It sounds like you're using the scheme interpreter from within Emacs. This is a good start for writing small functions, but you really want to use a REPL (Read-Eval-Print Loop) workflow. Thankfully, Emacs has a ready-made scheme REPL built-in, and has been mentioned elsewhere, there are additional modes (like Quack) that enhance the experience.
In the REPL model, you can freely type expressions in the interpreter if you want to try them out, but most of your coding should take place in the file you're writing. From within that buffer, if you have a scheme interpreter running (M-x run-scheme), then you can send sexps to the interpreter for evaluation without copying manually with C-c C-e. You can use C-M-x to do the same thing.
You can compile the entire file with C-c C-k, and if you have several expression you want to send together, grab them in a region and use C-c C-r to send the region to the interpreter.
There are several other commands that make transferring your code to interpreter easy; you can read more about them in your REPL session by pressing C-h m to describe the keybindings for your current mode.
What does this code even do ? Are you missing the "if" ? That could be part of the reason the interpreter isn't working.?
(if (good-enough? guess x) guess (improve guess x))
Sorry if I just don't understand what you are trying to achieve.