help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: el-search usage (doc, strings, pcase, etc.)


From: Garreau, Alexandre
Subject: Re: el-search usage (doc, strings, pcase, etc.)
Date: Sun, 28 Oct 2018 00:30:38 +0200
User-agent: Gnus (5.13), GNU Emacs 25.1.1 (i686-pc-linux-gnu, GTK+ Version 3.22.11) of 2017-09-15, modified by Debian

On 2018/10/27 at 22:19, Michael Heerdegen wrote:
> "Garreau, Alexandre" <galex-713@galex-713.eu> writes:
>
>> It’s pretty quick : translate your markdown/rst (which one?)
>
> Currently I only have the comment in the file header.

Yeah, and the package description in list-packages, and its related
-readme.txt file, looks like rst or markdown, that’s what I meant:
convert that comment to org-mode like structuration, so then you can use
the commentary extracted by packaging tool, export to texinfo, which
will convert to many other formats, including info.

>> Oh, indeed it works.  I would have expected C-p/C-n and arrow keys to
>> work too, like in M-x.  I only use M-p in real buffer such as with
>> comint-mode modes, barely with minibuffer (as I never wrote more than
>> two lines of text in it, and with a few lines M-p is only barely useful,
>> and C-p still work).  Normally using C-p with both `read-string' (which I
>> last used) and `read-from-minibuffer' (which el-search-pattern seems to
>> use) support it just as M-x…
>
> In emacs -Q, C-p and C-n don't browse the history for M-x.

Okay now that’s strange: here, C-p and C-n browse the history with M-x,
in emacs -Q, -q, etc.  Maybe debian modified it to do so?

However, if M-x accepts something, el-search input should be compatible
just the same, because both use read-* functions that behaves the same.
So if in your configuration M-x doesn’t accept C-p and C-n, then it’s
normal elsearch neither, but if in mine M-x does, elsearch should too.

> Also, in el-search, the pattern input buffer is in elisp-mode and
> often contains multiline input, so I decided that up and down move by
> lines.  That's beneficial when you write more complex patterns.

Yeah, like I regularely do with `eval-expression': wherever it is it or
M-x, C-p and C-n already move by lines, but when you’re at the first or
last line, respectively, instead of erring out “\(Beginning\|End\) of
buffer”, they browse history: much more expressive and handy.

>> Oh interesting, and it even support non-regexp patterns… but I find it
>> odd it use “string”.  I would have expected string to destructure in
>> characters just as the `string' function does in elisp…
>
> First of all I wanted a name that is short, because it is one of the
> most often used pattern types.  Any better idea?

What, this is specific to el-search? why that? I’m almost sure it could
be useful in pcase as well (did you try to propose it?).  Then, may I
change the definition of the macro, so not to accept regexps anymore, so
to use `search' instead?

#+BEGIN_SRC emacs-lisp
  (pcase-defmacro in (pattern)
    `(and (pred sequencep)
          sequence
          (guard (search pattern ,sequence))))
#+END_SRC

Now it works for all sequences, with the very extremely (let’s postulate
one-letter is not reasonable, so this is an extreme) short “in” name,
found in “inside”, “include”, “intra”, “inter”, “contain”, etc. (other
possibility was “sub”, already used as an abbreviated name for set
inclusion).  So now, to contrast with this oddly not-RE aware function,
we make the RE one:

#+BEGIN_SRC emacs-lisp
  (pcase-defmacro re (pattern)
    `(and (pred stringp)
          string
          (guard (string-match ,sequence string))))
#+END_SRC

Or, if you find that not understandable enough, you can choose instead
`re-in', but I find it redundant, as it is imply by the used re that it
is “in”, from the point you choose not to use el-re-specific \` and \'.

“regexp” is about the same size of “contain”, so I didn’t mind it.

>> > The available pattern types are listed in C-h f
>> > el-search-defined-patterns.  BTW, the arguments of `string' can also
>> > be an "extended regexp" - that's a regexp plus a list of bindings like
>> > in
>> >
>> >   (string (((case-fold-search nil)) "was"))
>> >
>> > which would match "I was" but not "I Was", or a predicate accepting a
>> > string.
>>
>> That’s pretty complex…  I hoped it was for pure text (so it’s easier to
>> enter “special” characters such as “\\” or “(”), not regexps… but
>> strangely it seems not to support “<” and “>” to match beginning/end of
>> words.
>
> A literal string match pattern is easy to implement:
>
> (el-search-defpattern string-literal (s)
>   `(string ,(regexp-quote s)))

This is so dirty, because in the end you quote a regexp to search it
with a regexp-matcher.  And as elisp is not that much optimized yet,
this is going to be slower, not speaking of making uselessly the
implementation more complex and difficult to understand.

> Matching beginning and end of words works with `string':
>
>   (string "\\<word\\>")

Damn! I forgot a backslash!  If only elisp RE weren’t two levels of
interpretation away from read (one for "\n" et all, the other for
RE-level "(" et al).

> In isearch, it's possible to enter only one backslash, but el-search
> patterns are sexps, so you must escape the escape character to get one
> escape character as in any Lisp expression.

Indeed.

>> > It doesn't have this feature (yet).  I guess I could add it, but
>> > el-search not really fits for the task.  You can combine patterns
>> > matching strings in any way.  For example, you could search for
>> > something like
>> >
>> >   (or (and (string REGEXP1) (string REGEXP2) (pred SOME-PRED))
>> >       SOMETHING-DIFFERENT))
>> >
>> > so it's not even always well-defined what is intended to be
>> > highlighted.
>>
>> I’d say: the return value of the last pattern, or everything if “t”.
>> So, with a pattern written this way, it would be the whole thing (or the
>> submatch matched by “SOMETHING-DIFFERENT”), while if written like “(or
>> (and (pred SOME-PRED) (string REGEXP1) (string REGEXP2))
>> SOMETHING-DIFFERENT))” it would *always* match the submatch.  But I’m
>> unaware of pcase implemantation.  It seems to be fairly complex, so it
>> might be complex as well to do something alike.
>
> Yeah, it's not that simple: patterns do not have return values, and side
> effects (like changing match data) for matching are tricky.

It’s sad they use side effects.  Maybe returning a pair of first char +
end char? so (cons (string-match ...) (match-end)), typically.  The
tricky part is it should be automatically inserted when using
string-match, so you don’t need to worry about it…  Or maybe defining it
as a pattern (but then it won’t work in other guards):

#+BEGIN_SRC emacs-lisp
  (pcase-defmacro string-match (pattern)
    `(and (pred stringp)
          string
          (guard (cons (string-match ,sequence string) (match-end)))))
#+END_SRC

Or rather: I wonder if using scoping (maybe it would require dynamical
binding? or maybe rather won’t work without lexical binding) you could
locally (using cl-flet, or macrolet) redefine string-match upon its
former definition, in the appropriated functions so that it returns a
cons of its result and the return value of `match-end'.

>> Normally a package should be usable withut defining any key.
>
> Well, it's usable without keys, but then you have no ... keys ... for
> going to the next match, etc, as you wanted.

That’s why I missed isearch: even if I had no key for isearch-forward,
it just works inside it, because it defines a mode where some normally
scrolling-related keys behaves semantically with respect to it: it would
be really handy if it was based on isearch and therefore compatible with
it.

>> That’s (part of) the whole point of package recommandation not to
>> define keys: users should decide how they access the interface.  And
>> then it’s preferable it’s if convenient of course but I find this
>> pushes a bit too much for binding keys: I’m bad at choices and finding
>> myself a prefix key will let me unsatisfied (and above all: require me
>> to learn them, which I don’t have (yet) the time or will to invest
>> in),
>
> Then I suggest to simply follow the suggestion in the commentary and use
> M-s e as prefix.

As I said, I don’t want to bind keys until I’m used to regularely use a
command: otherwise I’ll have really a hard time remembering the key, and
each time I want to call the command I’ll have to go back to my init.el
file to find for my keybindings, kill the buffer, return the original
one, then call the keybinding: in the end either I only use the command
name and forget the keys, or stop to use the command.  That’s what
happened to me a lot after discovering iy-go-to-char (which still suffer
from its quite nonsensical “iy” name), multiple-cursors, etc.  So
without a solution using semantical, common, potentially
scrolling-related, keys, I’ll keep doing “M-x <up> <return>”.

I will have no problem remembering what follow the prefix, if it’s
semantical enough, but I see no mnemotecnic reason for remembering the
prefix key sequence.

>> and the “shift” thing is specific to qwerty (“%” doesn’t use
>> shift on my keyboard, while others keys do (for instance “shift+%” is
>> “`” here)).
>
> Well, I can only predefine bindings, then you have to use these, or you
> have to make choices...

Yes of course.  It’s normal.  It’s only to note that making assumptions
on others layout is generally a bad idea (so refering to shift is more a
qwerty-local feature, otherwise it just happens all these keys are left
undefined by default)

> Do you use neo or something like that?

What is neo?

> Of course you can define bindings on your own, but there are quite a few
> in different maps needed, so I predefined the commands that can do this
> for the user for convenience.  I thought this would especially help
> people to try the package quickly.

Well it’s surely quicker than redefining everything.  But still requires
to open your init file, check for your keybindings (just in case), and
add this line, then keep in mind the prefix for the time of trying.
That’s well better than not defining anything, I’m just saying that for
an interaction that commonly request repetition, it would have been
better to have something like isearch.

Imho keystrokes are for doing something quicker when you need to do it
often or repetedly: otherwise commands names are what you use for
trying.  “For trying”, personally, I’ll never bother trying to check 2
to 5 times to remember the correct prefix.

>> Why not, by default, be compatible with isearch?  I’m not totally aware
>> yet of the whole implementation of isearch, but it seems like it’ based
>> on a mode: maybe a clean and modular way to do that would to make
>> derived-mode out of it? or find another way of reusing its library:
>> this way it would stay forward-compatible with it, and benefit from
>> further additions and improvements made to it.
>
> When I wrote el-search, I considered compatibility with isearch, but
> there are too many requirements for el-search that where incompatible
> or impossible to do with isearch ([…])  So incompatibility with
> Isearch is intentional, sorry.

Oh, that’s sad: then maybe something alike? like activating a mode with
a different keymap while the search, that’ll quit when triggering an
external key.

> matches completely inside matches; interruptible (multi-buffer)
> search and query-replace, concurrent match count in the background,
> and many more things

I didn’t understand what’s a single example of them (and not even
understood the syntax of the first (is one of “matches” a verb? are they
both substantive? if so do they refer to the same match?)).  If they’re
so important so to justify incompatibility with something so important
in emacs as isearch, maybe isearch should change, and potentially gain
these capabilities?  Did you try or asked its authors?



reply via email to

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