emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: find-tag-default


From: Drew Adams
Subject: RE: find-tag-default
Date: Sat, 29 May 2004 10:43:04 -0700

    D>     Library thingatpt+.el provides additions and enhancements to
thingatpt.el:
    D>
    D>     1) An optional syntax-table argument is used to determine the
bounds.

  RMS> When have you found that useful?

To be honest, I don't remember well. I wrote this a decade ago.

I believe it was in order to take into account different modes with
different syntax; that is, so that the different "things" would have an
appropriate syntax definition. The syntax-table is used to determine the
bounds of the thing searched for.

You can, for instance, look for the "word" nearest point, where you define
"word" in a special way by passing in an explicit syntax-table arg.
Likewise, with other kinds of things (defuns, whitespace, pages, ...).

The syntax table will affect the exact definition of what constitutes a
"word" etc. What makes such an entity usable as a "thing" here is of course
that it has corresponding forward-THING (or beginning-of-THING) and
end-of-THING operations. The two (syntax table and boundary-defining
operations) work hand in hand.

Remember that the "thing" functions are completely general: you can define
your own forward-whazit and end-whazit commands and one or more
syntax-tables that incorporate whazit syntax(es). Your forward-whazit
function could behave differently with different syntax tables. This then
gives you functions to pick whazits out of a buffer easily in different
(syntax) situations.

Consider, for instance, forward-symbol, which uses this regexp:
"\\(\\sw\\|\\s_\\)+" to determine what a "symbol" is. This in turn depends
on what \sw and \s  mean. That is, forward-symbol depends on the syntax
table: give it a different syntax table and you get different behavior.

BTW, I note that I removed the syntax-table arg from the symbol-* functions
because the mode of use (for me) was always emacs-lisp-mode; I just passed
emacs-lisp-mode-syntax-table in as the syntax-table arg when defining the
symbol-* functions. I kept the syntax-table arg for the other functions
(form-*, thing-*, word-*, sentence-*, sexp-*, number-*, list-*), however.

If used for other (e.g. other programming) modes, it might be good to
reinstate the syntax-table arg for the symbol-* functions too.

The syntax-table arg is in any case optional.

    D>     2) New functions (e.g. symbol-nearest-point) don't require point
to be on
    D>     the name you want. Here's how "nearest" is defined:

  RMS> Some kind of extension in this direction could be useful, I guess.
  RMS> However, I think this looks too far away from point:

    D>         The nearest symbol on the same line is returned, if there is
any.
    D>             Between two symbols equidistant from point on the same
line, the
    D>             leftmost is considered nearer.
    D>         Otherwise, neighboring lines are tried in sequence:
    D>             previous, next, 2nd previous, 2nd next, 3rd previous, 3rd
next, etc.
    D>             This means that between two symbols equidistant from
point in
    D>             lines above and below it, the symbol in the line above
point
    D>             (previous Nth) is considered nearer to it.

  RMS> I think it would be a mistake to use a symbol very far away from
point.
  RMS> The user would think, "Where in the world did that come from?"
  RMS> It's better to say "there's no default" than grasp at straws to
  RMS> find one.

  RMS> So I would recommend a new function along these lines but with
  RMS> some limits.

It only picks up a thing (symbol, list, number, whatever) far from point if
there is none closer. That is, it just picks the closest one. If there is a
lot of blank space, for instance, this will ignore that.

Or, if there is other stuff that should be ignored, then that is ignored.
That is, if the type of "thing" searched for is surrounded by non-things,
the non-things are ignored and the nearest thing is picked up. For instance,
if the type is a number, then this ignores anything that is not a number.

I think that an arbitrary limit would *not* be useful. In practice, there is
something useful nearby. If there is none, nil is returned. If the only
appropriate thing is pretty far away, it is still probably appropriate to
return it. The notion of "nearby" is relative, in any case: it can be
different for different situations. Only the calling code really knows what
"nearby" means.

Besides, a calling function can always choose to ignore something beyond a
certain limit. The *-with-bounds functions all return the bounds of the
found thing, and the bounds-of-* functions extract those bounds. The bounds
can be tested to filter things too far away, if necessary.

Of course it's possible that if this were executed on a humongous file,
performance would suffer. For this reason, it might be good to limit the
search beforehand, instead of waiting to filter out a result that is too far
away. This is easily done by narrowing: these functions stop at the limits
of the buffer - or of the narrowing restriction. Again, the calling function
knows best whether such narrowing (and how much) is appropriate.

You may be right that a user might think "whazzat?!" in some situations - I
dunno. My personal preference is to always have Emacs serve me such a
default value; if I don't like it I toss it from the minibuffer with a
simple backward-kill-sexp (bound to C-M-backspace). In my own code, I use
symbol-nearest-point in completing-read everywhere.

Anyway, whether or not such functions (or similar) are used directly in
interactive specs, I think they can serve as useful elisp building blocks.

 - Drew

For reference, here's the code:
http://www.emacswiki.org/elisp/thingatpt-plus.el







reply via email to

[Prev in Thread] Current Thread [Next in Thread]