[gnu.emacs.bug] lisp remarks

sarantos@PRINCETON.EDU (Sarantos Kapidakis) (06/14/89)

I have gathered some remarks about the lisp code of the emacs library.
Most of them are not bugs, just remarks (but very easy to fix, so I
mention them).

In the functions "indent-sexp" and "indent-c-exp",
the variable "inner-loop" is declared local, but the "innerloop" is
used instead.  So change instances of "innerloop" with "inner-loop".
Also, in the same functions, "last-depth" is used, but is not declared
as local.

In the same functions, there is no reason for calling
"calculate-lisp-indent" and "calculate-c-indent" without an argument
(so that parsing starts at the beginning of the defun).
You can always give the "opoint" as an argument.

In the function "indent-c-exp", the elements of "indent-stack" never
become negative, so there is no reason for comparing them against zero.
(In "indent-sexp", they may be set to a negative value).

The function "indent-c-command", when used with an argument, does
nothing, unless the line starts with a brace (after the indentation).
This is so, because it attempts a "forward-sexp" from the beginning
of the line, which in lines like:
	if (c) { ... <other lines> ... }
	else { ... <other lines> ... }
this first "sexp" is a token, and always ends on the same line.
One solution is to try to do the "forward-sexp" from the original
point that we were located on the line, not the beginning of it.
I don't like this solution, because then, depending on the position
of point in the line, a different region will be specified, and it
will be incompatible with the use of the command so far, and its use
in lisp-mode.
The solution I prefer, is to indent the first "sexp" that starts in
this line, and ends in a next one, if there is any.
This can be done by the code:
	   (save-excursion (forward-line 1) (setq beg (point)))
	   (while (< (point) beg)
	     (forward-sexp 1)
	     (setq end (point))
	     (skip-chars-forward " \t\n"))
replacing the code:
	  (setq beg (point))
	  (forward-sexp 1)
	  (setq end (point))
	  (goto-char beg)
	  (forward-line 1)
	  (setq beg (point)))
The code I am suggesting is not really slower than the code to be
replaced, since it just scans the "sexp" in only one more line.

Here I should also mention that I would prefer that the function
"indent-c-command", was just:
  (if (or whole-exp ps-tab-always-indent 
	     (save-excursion (skip-chars-backward " \t") (bolp)))
      (ps-indent-line whole-exp)
    (insert-tab))
just to decide if a tab will be used or not,
and "indent-c-line" to do the rest of the job,
having exactly the same functionality as in lisp-mode.

Now I should mention the real problems that I have:
In c-mode, some "case" lines are not indented correctly.
The reason is the pattern that they are matched against is
"case[ \t]", while these lines are like: "case'a':"
In C, it is also legal to have not only a character constant,
but also comment (!), parenthesized expression and maybe more
just after the "case" token.  So in my opinion, the regular expression
should be something like: "case\\b", although "case[ \t'/(]" may do
the same job (unless I forgot some cases).
It is not a big deal, but it easy to fix.

Another problem that I have, is that checkpoint files are not always
removed (I think this happens if changes are discarded), filling my
directories with garbage files.  Is there any way to force this happen ?

I also need your advice on the use of "defconst" and "defvar".
Let me describe the situation:
I am writing a new module, in a file to be autoloaded.
If I use "defconst", I cannot customize this variable in my ".emacs"
file, because the definition will be overwritten when the file is
autoloaded.  So "defconst" is of no use to me.
In that case I use "defvar", since I want to assosiate a documentation
string with the value.
Some of these variables may be local variables to a buffer (declared
so on the mode hook function), when the file is autoloaded.
I have never assigned a global value to these variables.
Now I have two problems:
The global value of the variable is not void nay more, but nil
(since I have created the buffer local variable), so the "defvar"
has no effect.  What can I do to avoid that ?
I want, when I autoload the file, "defvar" to try to change the
global variable, not the buffer local one (and this global variable
to be void if I have never set it, even if I have made local variables
with the same names).
Using "setq" will not solve the problem, since I overwrite any default
value (which can be nil in some cases).

I am building some modules (like ps-mode (postscript), awk-mode,
compile-file (a better interface for compilation, using most of the
same functions), which when I complete, and test for some time,
I will contribute them to your library.
You have done a very nice job.

One last request:
On my compile-file module (which I believe will later be part of
your compile module) I use the "compile1" function, but with one
variation: I don't want it to save any buffers.
So I have copied the "compile1" code, and I removed that statement,
the "(save-some-buffers)", the first statement called from "compile1".
This is ok so far, but I don't like duplicated code.
I believe that in the future (so why not from now), this statement
can be removed from the "compile1" function and adeed to its present
callers, the functions "compile" and "grep".
(Even symantically, compilation and buffer saving are different).

thanks,
I am looking forward to an answer
sarantos