GNU bug report logs - #76423
Major-mode provided LSP server for Eglot

Previous Next

Package: emacs;

Reported by: Stefan Monnier <monnier <at> iro.umontreal.ca>

Date: Wed, 19 Feb 2025 20:34:02 UTC

Severity: wishlist

Tags: patch

To reply to this bug, email your comments to 76423 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to monnier <at> iro.umontreal.ca, joaotavora <at> gmail.com, unhammer <at> fsfe.org, bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Wed, 19 Feb 2025 20:34:03 GMT) Full text and rfc822 format available.

Acknowledgement sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
New bug report received and forwarded. Copy sent to monnier <at> iro.umontreal.ca, joaotavora <at> gmail.com, unhammer <at> fsfe.org, bug-gnu-emacs <at> gnu.org. (Wed, 19 Feb 2025 20:34:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: bug-gnu-emacs <at> gnu.org
Subject: Major-mode provided LSP server for Eglot
Date: Wed, 19 Feb 2025 15:33:07 -0500
[Message part 1 (text/plain, inline)]
Tags: patch

Tags: patch

Eglot should make it easier for major modes to suggest which LSP
server to use.
Currently major modes end up doing funny dances like:

    branch: externals/bicep-ts-mode
    commit 8192a400fae45cdde32526f96bb7ed5158d98008
    Author: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>
    Commit: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>
    
        Wait with altering eglot-server-programs until eglot loaded
    ---
     bicep-ts-mode.el | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/bicep-ts-mode.el b/bicep-ts-mode.el
    index 204629b4c6..f047bccae0 100644
    --- a/bicep-ts-mode.el
    +++ b/bicep-ts-mode.el
    @@ -205,11 +205,11 @@ Return nil if there is no name or if NODE is not a defun node."
                                            . bicep-ts-mode))))
     
     ;;;###autoload
    -(and (boundp 'eglot-server-programs)
    -     (file-exists-p (bicep-langserver-path))
    -     (progn
    -       (add-to-list 'eglot-server-programs
    -                    `(bicep-ts-mode . ("dotnet" ,(bicep-langserver-path))))))
    +(eval-after-load 'eglot
    +  '(and (file-exists-p (bicep-langserver-path))
    +        (progn
    +          (add-to-list 'eglot-server-programs
    +                       `(bicep-ts-mode . ("dotnet" ,(bicep-langserver-path)))))))
     
     (provide 'bicep-ts-mode)

The patch below would let this major modes do it with a simple:

      (setq-local eglot-server-programs
                  `(bicep-ts-mode . ("dotnet" ,(bicep-langserver-path))))


- Stefan


[eglot-server.patch (text/patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Wed, 19 Feb 2025 21:53:03 GMT) Full text and rfc822 format available.

Message #8 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: Felician Nemeth <felician.nemeth <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>, 76423 <at> debbugs.gnu.org,
 João Távora <joaotavora <at> gmail.com>
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Wed, 19 Feb 2025 22:52:25 +0100
Stefan Monnier via "Bug reports for GNU Emacs, the Swiss army knife of
text editors" <bug-gnu-emacs <at> gnu.org> writes:

> Eglot should make it easier for major modes to suggest which LSP
> server to use.

> The patch below would let this major modes do it with a simple:
>
>       (setq-local eglot-server-programs
>                   `(bicep-ts-mode . ("dotnet" ,(bicep-langserver-path))))

Wouldn't the patch make harder for the users to customize Eglot to use
their preferred LSP server instead of the server suggested by the major
mode?

Thanks,
Felicián

>
> - Stefan
>
>
> diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
> index bd28174e7da..3aff922be1d 100644
> --- a/lisp/progmodes/eglot.el
> +++ b/lisp/progmodes/eglot.el
> @@ -235,6 +235,10 @@ eglot-alternatives
>                        when probe return (cons probe args)
>                        finally (funcall err)))))))
>  
> +(defvar-local eglot-server-program nil
> +  "Description of the server to use.
> +Follows the same syntax as any element of `eglot-server-programs', ")
> +
>  (defvar eglot-server-programs
>    ;; FIXME: Maybe this info should be distributed into the major modes
>    ;; themselves where they could set a buffer-local `eglot-server-program'
> @@ -354,7 +358,7 @@ eglot-server-programs
>  
>  * In the most common case, a symbol such as `c-mode';
>  
> -* A list (MAJOR-MODE-SYMBOL :LANGUAGE-ID ID) where
> +* A list (MAJOR-MODE-SYMBOL :language-id ID) where
>    MAJOR-MODE-SYMBOL is the aforementioned symbol and ID is a
>    string identifying the language to the server;
>  
> @@ -1331,7 +1335,9 @@ eglot--lookup-mode
>                                          (replace-regexp-in-string
>                                           "\\(?:-ts\\)?-mode$" ""
>                                           (symbol-name sym))))))
> -   for (modes . contact) in eglot-server-programs
> +   for (modes . contact) in (if (null eglot-server-program)
> +                                eglot-server-programs
> +                              (cons eglot-server-program eglot-server-programs))
>     for llists = (mapcar #'eglot--ensure-list
>                          (if (or (symbolp modes) (keywordp (cadr modes)))
>                              (list modes) modes))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Wed, 19 Feb 2025 22:23:02 GMT) Full text and rfc822 format available.

Message #11 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Felician Nemeth <felician.nemeth <at> gmail.com>
Cc: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>, 76423 <at> debbugs.gnu.org,
 João Távora <joaotavora <at> gmail.com>
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Wed, 19 Feb 2025 17:22:29 -0500
>> Eglot should make it easier for major modes to suggest which LSP
>> server to use.
>
>> The patch below would let this major modes do it with a simple:
>>
>>       (setq-local eglot-server-programs
>>                   `(bicep-ts-mode . ("dotnet" ,(bicep-langserver-path))))
>
> Wouldn't the patch make harder for the users to customize Eglot to use
> their preferred LSP server instead of the server suggested by the major
> mode?

Could be, tho it depends.
AFAIK they can't use Customize to do that because packages (like
`bicep-ts-mode.el`) modify the variable outside of Customize's control,
so currently they have to do something like:

    (add-to-list 'eglot-server-programs '(bicep-ts-mode . MYSERVER))

which may need to be adjusted to

    (with-eval-after-load 'eglot
      (add-to-list 'eglot-server-programs '(bicep-ts-mode . MYSERVER)))

or

    (with-eval-after-load 'bicep-ts-mode
      (add-to-list 'eglot-server-programs '(bicep-ts-mode . MYSERVER)))

With the variable I suggest I guess they'd have to do

    (add-hook 'bicep-ts-mode-hook
      (lambda () (setq-local eglot-server-program '(bicep-ts-mode . MYSERVER))))

I know some people find `add-hook` and `lambda` more scary than
`eval-after-load` and `add-to-list`, so I guess it would count as
"harder", yes.

Maybe we should offer an actual `defcustom` variable for user overrides,
if we care enough.  Personally, I prefer to work on making the
`add-hook+lambda` approach more accessible, because it's just very
flexible and powerful, so it's much more generally useful.
One such effort is to use `use-package` or `setup`.


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Thu, 20 Feb 2025 10:19:02 GMT) Full text and rfc822 format available.

Message #14 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: Felician Nemeth <felician.nemeth <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>, 76423 <at> debbugs.gnu.org,
 João Távora <joaotavora <at> gmail.com>
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Thu, 20 Feb 2025 11:18:16 +0100
>> Wouldn't the patch make harder for the users to customize Eglot to use
>> their preferred LSP server instead of the server suggested by the major
>> mode?
>
> Could be, tho it depends.

To me it seems both the current and the proposed approaches are too
complex for newbies, but quite straightforward to write with a little
bit of elisp knowledge.  So maybe it is enough to add some simple
examples to the documentation.

Or we could have two variables defining server-programs:
eglot-user-server-programs and eglot-server-programs (alternatively
eglot-server-programs and eglot-default-server-programs.  Where the
former is only set by the users and it takes precedence over the latter
if there is a match in it.  But it is possible that I'm once again
overthinking this.

Felicián




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Thu, 20 Feb 2025 10:56:02 GMT) Full text and rfc822 format available.

Message #17 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>
To: Felician Nemeth <felician.nemeth <at> gmail.com>
Cc: 76423 <at> debbugs.gnu.org, Stefan Monnier <monnier <at> iro.umontreal.ca>,
 João Távora <joaotavora <at> gmail.com>
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Thu, 20 Feb 2025 11:55:05 +0100
>>> Wouldn't the patch make harder for the users to customize Eglot to use
>>> their preferred LSP server instead of the server suggested by the major
>>> mode?
>>
>> Could be, tho it depends.
>
> To me it seems both the current and the proposed approaches are too
> complex for newbies, but quite straightforward to write with a little
> bit of elisp knowledge.  So maybe it is enough to add some simple
> examples to the documentation.
>
> Or we could have two variables defining server-programs:
> eglot-user-server-programs and eglot-server-programs (alternatively
> eglot-server-programs and eglot-default-server-programs.  Where the
> former is only set by the users and it takes precedence over the latter
> if there is a match in it.  But it is possible that I'm once again
> overthinking this.

I would prefer that solution over users having to understand and/or
copy-paste lambdas, eval-after-loads and setq-locals.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Thu, 20 Feb 2025 20:00:03 GMT) Full text and rfc822 format available.

Message #20 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: João Távora <joaotavora <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>, 76423 <at> debbugs.gnu.org
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Thu, 20 Feb 2025 19:59:44 +0000
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

Hi Stefan,

> The patch below would let this major modes do it with a simple:
>
>       (setq-local eglot-server-programs
>                   `(bicep-ts-mode . ("dotnet"
>       ,(bicep-langserver-path))))

You mean eglot-server-program, singular (that's what your patch proposes)

Anyway, your patch is more or less what I had in mind altough:

* The name should probably be something less confusable with
  e-s-programs, like eglot-suggested-servers or eglot-preferred-servers
  (note that it can still be "servers!" unless we purposedly cap that
  ability, which we maybe should).

* It's a bit silly to repeat the major-mode symbol in it.  So the
  setting in the major-mode function should be something like

    (setq eglot-suggested-servers '("dotnet" ,(bicep-langserver-path)))

As to the precedence logic which you all discussed in the following
emails, I think it is indeed a problem.  But I don't see a problem in
prioritizing eglot-suggested-servers.

* The user can always nullify it with a

   (add-hook 'foo-mode-hook
     (lambda () (setq eglot-suggested-server nil)))

  I don't see this as a hindrance and I don't want to add much extra
  logic to Eglot to manage this for users afraid of add-hook.  The Eglot
  manual already uses these add-hook snippets and as long as people know
  to copy-paste.  If people want to the use-package macro magic to keep
  themselves ignorant of how Emacs works, I think that's a mistake, but
  this shouldn't stop them.

* Nevertheless it should be possible to add some logic to eglot.el to
  discover if the e-s-programs variable has been modified.

* It's important to note that this effort by itself won't bring many
  advantages until major-modes can somehow know during their normal
  working that eglot-suggested-servers hasn't been touched and that a
  particularly friendly server has effectively been started (either by
  M-x eglot or by the major mode itself, with appropriate care).  Then,
  foo-mode will be able to provide specific `M-x foo-thingamabob`
  commands that make use of an LSP connection, much like python.el or
  ruby-mode.el provide commands to send a region to the interpreter,
  etc.

* I'm against adding eglot-server-user-programs or somesuch as someone
  is proposing.  I only want to add a new variable to be settable by the
  major mode.  And ideally it should come with examples of major-mode
  patches with such added functionality for the "friendly server", else
  what is the point of having the major mode even set it?

João

PS: something that I didn't mention in my recent reply to a patch about
this in the mailing list by Philip Kaludercic (posted to emacs-devel I
think) is that none of these efforts shall break eglot.el from being
compiled and loaded in older Emacsen (his patch did that).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Thu, 20 Feb 2025 20:02:03 GMT) Full text and rfc822 format available.

Message #23 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: João Távora <joaotavora <at> gmail.com>
To: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>
Cc: 76423 <at> debbugs.gnu.org, Felician Nemeth <felician.nemeth <at> gmail.com>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Thu, 20 Feb 2025 20:01:15 +0000
Kevin Brubeck Unhammer <unhammer <at> fsfe.org> writes:

>>>> Wouldn't the patch make harder for the users to customize Eglot to use
>>>> their preferred LSP server instead of the server suggested by the major
>>>> mode?
>>>
>>> Could be, tho it depends.
>>
>> To me it seems both the current and the proposed approaches are too
>> complex for newbies, but quite straightforward to write with a little
>> bit of elisp knowledge.  So maybe it is enough to add some simple
>> examples to the documentation.

Who wrote this?  I agree :-)

>> Or we could have two variables defining server-programs:
>> eglot-user-server-programs and eglot-server-programs (alternatively
>> eglot-server-programs and eglot-default-server-programs.  Where the
>> former is only set by the users and it takes precedence over the latter
>> if there is a match in it.  But it is possible that I'm once again
>> overthinking this.

No.

> I would prefer that solution over users having to understand and/or
> copy-paste lambdas, eval-after-loads and setq-locals.

Please see my reply to Stefan.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Thu, 20 Feb 2025 21:13:02 GMT) Full text and rfc822 format available.

Message #26 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: João Távora <joaotavora <at> gmail.com>
Cc: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>, 76423 <at> debbugs.gnu.org
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Thu, 20 Feb 2025 16:12:27 -0500
>>       (setq-local eglot-server-programs
>>                   `(bicep-ts-mode . ("dotnet"
>>       ,(bicep-langserver-path))))
>
> You mean eglot-server-program, singular (that's what your patch proposes)

Oops, yes.

> Anyway, your patch is more or less what I had in mind altough:
>
> * The name should probably be something less confusable with
>   e-s-programs, like eglot-suggested-servers or eglot-preferred-servers
>   (note that it can still be "servers!" unless we purposedly cap that
>   ability, which we maybe should).

I have no opinion on the name.

> * It's a bit silly to repeat the major-mode symbol in it.  So the
>   setting in the major-mode function should be something like
>
>     (setq eglot-suggested-servers '("dotnet" ,(bicep-langserver-path)))

That's what I started with but then I saw that `eglot--lookup-mode`
returns info that includes part of the `car` of the elements in
`eglot-server-programs` (IIUC it's so as to know which other buffers and
major modes could share the same server), so rather than try and learn
how that part of Eglot really works, I went for a simpler change.


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Thu, 20 Feb 2025 23:56:02 GMT) Full text and rfc822 format available.

Message #29 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: João Távora <joaotavora <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>, 76423 <at> debbugs.gnu.org
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Thu, 20 Feb 2025 23:55:48 +0000
On Thu, Feb 20, 2025 at 9:12 PM Stefan Monnier <monnier <at> iro.umontreal.ca> wrote:
>
> >>       (setq-local eglot-server-programs
> >>                   `(bicep-ts-mode . ("dotnet"
> >>       ,(bicep-langserver-path))))
> >
> > You mean eglot-server-program, singular (that's what your patch proposes)
>
> Oops, yes.
>
> > Anyway, your patch is more or less what I had in mind altough:
> >
> > * The name should probably be something less confusable with
> >   e-s-programs, like eglot-suggested-servers or eglot-preferred-servers
> >   (note that it can still be "servers!" unless we purposedly cap that
> >   ability, which we maybe should).
>
> I have no opinion on the name.
>
> > * It's a bit silly to repeat the major-mode symbol in it.  So the
> >   setting in the major-mode function should be something like
> >
> >     (setq eglot-suggested-servers '("dotnet" ,(bicep-langserver-path)))
>
> That's what I started with but then I saw that `eglot--lookup-mode`
> returns info that includes part of the `car` of the elements in
> `eglot-server-programs` (IIUC it's so as to know which other buffers and
> major modes could share the same server), so rather than try and learn
> how that part of Eglot really works, I went for a simpler change.

Right, I see. But to do these kinds of changes to Eglot, "how Eglot
really works" is a prerequisite :-)  And you have understood it,
in essence.

The thing is, we're going to bump into that old "mapping the language"
can of worms eventually. Language servers are for languages, so
as it stands what major modes may want to say is "I want to participate
in managing this language".  But even that is fairly awkward.  To do
this right, we'd really need a language hook. And I have 0 time to open
that can of worms.

As it stands, looking at the `eval-after-load' code for bicep-ts-mode,
I wonder if it is really a "funny dance" or just the way it should be
until past decisions are revisited (but not by me :-))

João




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Fri, 21 Feb 2025 03:06:02 GMT) Full text and rfc822 format available.

Message #32 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: João Távora <joaotavora <at> gmail.com>
Cc: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>, 76423 <at> debbugs.gnu.org
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Thu, 20 Feb 2025 22:04:50 -0500
> As it stands, looking at the `eval-after-load' code for bicep-ts-mode,
> I wonder if it is really a "funny dance" or just the way it should be
> until past decisions are revisited (but not by me :-))

Having to play such games just to update some kind of central DB of all
the modes seems really silly when the DB is only ever consulted for the
major mode of current buffer.


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#76423; Package emacs. (Fri, 21 Feb 2025 09:50:03 GMT) Full text and rfc822 format available.

Message #35 received at 76423 <at> debbugs.gnu.org (full text, mbox):

From: João Távora <joaotavora <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Kevin Brubeck Unhammer <unhammer <at> fsfe.org>, 76423 <at> debbugs.gnu.org
Subject: Re: bug#76423: Major-mode provided LSP server for Eglot
Date: Fri, 21 Feb 2025 09:49:32 +0000
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

>> As it stands, looking at the `eval-after-load' code for bicep-ts-mode,
>> I wonder if it is really a "funny dance" or just the way it should be
>> until past decisions are revisited (but not by me :-))
>
> Having to play such games just to update some kind of central DB of all
> the modes seems really silly when the DB is only ever consulted for the
> major mode of current buffer.

Let see:

- Is it so?  Something is only really "silly" if it serves no purpose
  beyond its exhuberance or idiosyncrasy.  If you were to take away the
  "silly" centralized e-s-programs db now -- like someone recently
  naively suggested -- you would break eglot.el as loaded in older
  Emacsen, and that would upset a fair number of people.  Of course, you
  could move it into compat.el (no longer in use by Eglot) and maintain
  it there.  You would only be increasing the level of silliness.

- Everything in Emacs happens in a buffer and in a major mode, and the
  only useful hookage we get to set things up before minor modes kick in
  is tied to those, so any db -- centralized or not -- is going to be
  consulted within those boundaries.

- LSP stands for Language Server Protocol, and its mapped to the concept
  of "language".  As is much other tooling outside the Emacs ecosystem
  (frequently utterly uninterested in what a "major mode" is).
  Snippets, syntax highlighters, linters etc.  The fact that there is no
  easy way to "run this bit of code if the current buffer is in this
  language" is IMO a very glaring omission in an editor which is
  frequently used for source code.

- Your patch would probably work for biceps-ts-mode and whatever
  "Biceps" is but when dealing with major modes that must cooperate with
  each other (c-mode and c-ts-mode ... json-mode and json-js-mode,
  tuareg-mode and ocaml-mode, many others) etc, it would lead to
  repetition and duplication: a newcomer mode would always need to beg
  the maintainers of other major modes to reference it.  Dead modes
  would linger around scattered.  Duplication, at least in my book,
  always tips the pendulum of silliness towards it.

So, again, until past decisions are revisited (that bug#somesuch of 1/2
years ago) and there exists a way for a major mode to say "I serve this
language and I want to suggest a language server for it so that other
modes that also serve it can use it" I think the current state of
affairs is the best we have.

What real problem is there in the current biceps-ts-mode.el code?
Doesn't it work?  There is no duplication.  It's a DRY and idempotent
statement.  It is a dislike of eval-after-load?  In that case, if
loading order is the problem, maybe `add-hook` semantics (which solves
the same problem by other means) could be leveraged.  But unless a real
problem (and a real solution) can be presented just calling out the
formal exhuberance of a solution is no real argument for change.

João




Severity set to 'wishlist' from 'normal' Request was from Stefan Kangas <stefankangas <at> gmail.com> to control <at> debbugs.gnu.org. (Sun, 23 Feb 2025 00:00:02 GMT) Full text and rfc822 format available.

This bug report was last modified 112 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.