Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

jump between if-fi

39 views
Skip to first unread message

rea...@newsguy.com

unread,
Dec 30, 2007, 6:02:01 PM12/30/07
to help-gn...@gnu.org
I hope this isn't one of those things that is just plain obvious to
lookup in emacs but I'm striking out with M-x apropos

How can I make emacs do something similar with if-fi constructs as it
does with parens?

Even better I'd like the kind of behaviour one can get in vim with
parens, where not only does the syntax coloring show the other paren
but you can jump there with a Ctrl-%

I know emacs can do that as well but not as easily. But anyway, I use
emacs more and would like to turn its powers used in paren recognition
against the `if fi', `while done', `for done'... etc. one uses in
shell scripting.

Lennart Borgman (gmail)

unread,
Dec 30, 2007, 6:23:07 PM12/30/07
to rea...@newsguy.com, help-gn...@gnu.org
rea...@newsguy.com wrote:
> I hope this isn't one of those things that is just plain obvious to
> lookup in emacs but I'm striking out with M-x apropos
>
> How can I make emacs do something similar with if-fi constructs as it
> does with parens?
>
> Even better I'd like the kind of behaviour one can get in vim with
> parens, where not only does the syntax coloring show the other paren
> but you can jump there with a Ctrl-%

Maybe you mean %, not C-%?

You can in Emacs too, using Viper. But see

http://www.emacswiki.org/cgi-bin/wiki/ViKeys
http://www.emacswiki.org/cgi-bin/wiki/ViAndEmacs

rea...@newsguy.com

unread,
Dec 31, 2007, 1:29:16 AM12/31/07
to help-gn...@gnu.org
"Lennart Borgman (gmail)" <lennart...@gmail.com> writes:

> rea...@newsguy.com wrote:
>> I hope this isn't one of those things that is just plain obvious to
>> lookup in emacs but I'm striking out with M-x apropos
>>
>> How can I make emacs do something similar with if-fi constructs as it
>> does with parens?
>>
>> Even better I'd like the kind of behaviour one can get in vim with
>> parens, where not only does the syntax coloring show the other paren
>> but you can jump there with a Ctrl-%
>
> Maybe you mean %, not C-%?

Yes I did.

Thanks for those ... I knew some it but found some more.
But no, I don't want to try to turn emacs into vi so much as turn
emacs power loose on if-fi while-done etc constructs.

>> I know emacs can do that as well but not as easily. But anyway, I use
>> emacs more and would like to turn its powers used in paren recognition
>> against the `if fi', `while done', `for done'... etc. one uses in
>> shell scripting.

That was my my main question and I didn't notice anything on those
sites about that... I hope I just missed it.

So still wondering how to get paren type actions to work on if-fi type
shell constructs.

Thierry Volpiatto

unread,
Dec 31, 2007, 3:12:25 AM12/31/07
to rea...@newsguy.com, help-gn...@gnu.org
rea...@newsguy.com writes:

While you are in a script shell you have keybindings for case, if,
while getopts, etc... to construct all this statements.
If you do C-h m you will find them.
--
A+ Thierry
Pub key: http://pgp.mit.edu


rea...@newsguy.com

unread,
Dec 31, 2007, 9:41:38 AM12/31/07
to help-gn...@gnu.org
Thierry Volpiatto <thierry....@gmail.com> writes:

>> So still wondering how to get paren type actions to work on if-fi type
>> shell constructs.
>
> While you are in a script shell you have keybindings for case, if,
> while getopts, etc... to construct all this statements.
> If you do C-h m you will find them.

Maybe they are buried in there somewhere ... I don't see them.
Unless you are talking about the commands that insert a framework for
case while etc.

Or maybe you are referring to M-e M-a which don't really do what I
asked about not even close really.

I'm not asking about how to insert an if-fi statement... I'm asking
how to put the cursor on the `fi' part and jump to the `if' part. Or
on the `for' and jump to the `done'.

Or at least behave like emacs does with parens. Place cursor just
after `fi' and the `if' is highlighted

Alan Mackenzie

unread,
Dec 31, 2007, 11:24:38 AM12/31/07
to rea...@newsguy.com, help-gn...@gnu.org
Hi, Reader!

On Sun, Dec 30, 2007 at 05:02:01PM -0600, rea...@newsguy.com wrote:
> I hope this isn't one of those things that is just plain obvious to
> lookup in emacs but I'm striking out with M-x apropos

> How can I make emacs do something similar with if-fi constructs as it
> does with parens?

> Even better I'd like the kind of behaviour one can get in vim with
> parens, where not only does the syntax coloring show the other paren
> but you can jump there with a Ctrl-%

> I know emacs can do that as well but not as easily. But anyway, I use


> emacs more and would like to turn its powers used in paren recognition
> against the `if fi', `while done', `for done'... etc. one uses in
> shell scripting.

This is a moderately difficult exercise in Elisp programming. I would
suggest something like this:

(i) On the i of if, the i of fi, the w of when, the e of done etc., put
"syntax-table" text properties of open-parenthesis and
close-parenthesis. See pages "Syntax Table Internals", "Text
Properties" and "Special Properties" in the Emacs Lisp manual.

(ii) The best way to apply these text properties might be using
abbreviations - make "if" an abbreviation for "if" together with
applying the property. You'll need to check that the "if" isn't inside
a comment or string, and this sort of thing. See page "Abbrevs" and its
sub-pages, particularly the HOOK facility in page "Defining Abbrevs".
Then again, maybe just using (iii) (below) might be better.

(iii) You'll need some way of removing the properties when they
should'nt be there any more - for example, when you comment out a line,
or when you type the "n" of "find". You'll need an after-change
function here (page "Change Hooks" in the manual) which analyses the
text you're changing. Beware that font-locking sometimes uses
text-properties, and you might need to synchronise with it. Be aware
also that some people (including one Emacs core developer) disable font
locking because it annoys them.

When you've got it working, please submit it to Emacs for inclusion in
Emacs 23! Best of luck!

--
Alan Mackenzie (Nuremberg, Germany).


rea...@newsguy.com

unread,
Dec 31, 2007, 9:29:28 PM12/31/07
to help-gn...@gnu.org
Alan Mackenzie <a...@muc.de> writes:

> Hi, Reader!

[...]

> This is a moderately difficult exercise in Elisp programming. I would
> suggest something like this:
>

He-he... whats moderate for you appears to be clear over the top for me.

[...] snipped a very nice outline of how to go at it.

>
> When you've got it working, please submit it to Emacs for inclusion in
> Emacs 23! Best of luck!

Yes that would be very nice but is also very unlikely. My skill level
would have to be improved several hundred percentage points in a
pretty short while.

I guess not too many emacs developers really do much shell scripting.
Probably using a lot more high level scripting languages (perl, lisp,
python and etc). I run into portability problems more with shell
scripts since something like perl is the same everywhere.

My perl is coming along well enough to use it for all scripting but I
still have many older shell scripts I'd hate to have to convert.

On a slightly different subject... if I may torture the threading
rules a little:
Speaking of portability... I'd like to get my emacs init files to be
more portable from one machine to the next but one I'm dealing with
now has different keyboard responses than most of the others and
requires differnt keybindings for delete-backward-char and a few
other things.

I'd like to include those in .emacs but don't know how to separate
them off by making them depend on which host emacs is running on.

Can you give me a push in that direction?

How to access the env variable HOSTNAME or slurp the results of the
hostname shell command and make the keybindings dependant on the
results.

I've seen examples of something similar where the code tests if its
fsf emacs or Xemacs as a condition.

Alan Mackenzie

unread,
Jan 1, 2008, 9:18:27 AM1/1/08
to rea...@newsguy.com, help-gn...@gnu.org
Hi again, and Happy New Year, Reader!

On Mon, Dec 31, 2007 at 08:29:28PM -0600, rea...@newsguy.com wrote:
> Alan Mackenzie <a...@muc.de> writes:

> > This is a moderately difficult exercise in Elisp programming. I
> > would suggest something like this:

> He-he... whats moderate for you appears to be clear over the top for me.

Don't underestimate yourself. After all, you've mastered shell script.

> [...] snipped a very nice outline of how to go at it.


> > When you've got it working, please submit it to Emacs for inclusion
> > in Emacs 23! Best of luck!

> Yes that would be very nice but is also very unlikely. My skill level
> would have to be improved several hundred percentage points in a pretty
> short while.

Indeed. Where's the problem with that? The Emacs documentation
(including that for Emac Lisp) is sensationally good, and there's as much
help as you need on the net. For functionality this useful, I'd happily
help you by personal email, even several times a week.

This is an ideal problem for getting into heavy elisping - it goes to the
core of Emacs, with hooks, text-properties/overlays, textual analysis
with regular expressions - yet it is tightly enough defined that you
won't just drift into an endless maze of discouraging vagueness and
complexity. After implementing this, you would be welcomed with open
arms by the core Emacs team.

So, how long would all this take? Several weeks, assuming ~15-30 hours
hacking time per week.

> I guess not too many emacs developers really do much shell scripting.
> Probably using a lot more high level scripting languages (perl, lisp,
> python and etc). I run into portability problems more with shell
> scripts since something like perl is the same everywhere.

I would think most Emacsers write shell scripts reasonably fluently.
Lisp isn't really suited for the job, and p{erl,ython} seem over
complicated. In my humble opinion, of course. ;-)

> My perl is coming along well enough to use it for all scripting but I
> still have many older shell scripts I'd hate to have to convert.

So, why convert them?

[ .... ]

--
Alan Mackenzie (Nuremberg, Germany)


rea...@newsguy.com

unread,
Jan 1, 2008, 10:39:41 AM1/1/08
to help-gn...@gnu.org
Alan Mackenzie <a...@muc.de> writes:

[...]

>> Yes that would be very nice but is also very unlikely. My skill level
>> would have to be improved several hundred percentage points in a pretty
>> short while.
>
> Indeed. Where's the problem with that? The Emacs documentation
> (including that for Emac Lisp) is sensationally good, and there's as much
> help as you need on the net. For functionality this useful, I'd happily
> help you by personal email, even several times a week.

time

And as you noted.. elisp isn't well suited for scripting so I'm
working on perl.

[...]

>> I guess not too many emacs developers really do much shell scripting.
>> Probably using a lot more high level scripting languages (perl, lisp,
>> python and etc). I run into portability problems more with shell
>> scripts since something like perl is the same everywhere.
>
> I would think most Emacsers write shell scripts reasonably fluently.
> Lisp isn't really suited for the job, and p{erl,ython} seem over
> complicated. In my humble opinion, of course. ;-)

I'm sure they are fluent. Way more than I am.

What I said was I doubt they use shell languages as much as someone
who isn't fluent in perl or python. What I was getting at is there
may not be much of a perceived need for things that aid shell
scripting. All the higher level stuff uses parens rather than if-fi.

I do agree though that hacking out something to make emacs able to
recognize shell constructs like it does with parens would be a great
learning tool and of some value to the emacs community. God knows I
owe the community a huge debt for all the help over the years.

I may have to dig into it this new year.

Alan Mackenzie

unread,
Jan 1, 2008, 10:53:04 AM1/1/08
to rea...@newsguy.com, help-gn...@gnu.org
Hi, Reader!

On Mon, Dec 31, 2007 at 08:29:28PM -0600, rea...@newsguy.com wrote:

[ .... ]

> On a slightly different subject... if I may torture the threading
> rules a little:
> Speaking of portability... I'd like to get my emacs init files to be
> more portable from one machine to the next but one I'm dealing with
> now has different keyboard responses than most of the others and
> requires differnt keybindings for delete-backward-char and a few
> other things.

Have a look at the "Key Bindings" in the Emacs FAQ.

There are several variables you can test to find out what system you're
running under: system-type, system-name, .... Have a look at page
"System Interface" in the Elisp manual.

> I'd like to include those in .emacs but don't know how to separate
> them off by making them depend on which host emacs is running on.

> Can you give me a push in that direction?

(if (eq system-type 'gnu/linux)
(progn
....)
(...)
....)

(if (eq window-system 'x) .....) ; See elisp manual page "Window Systems"

> How to access the env variable HOSTNAME or slurp the results of the
> hostname shell command and make the keybindings dependant on the
> results.

(getenv "HOSTNAME") ; See elisp manual page "System Environment"

> I've seen examples of something similar where the code tests if its
> fsf emacs or Xemacs as a condition.

I think you mean "GNU Emacs". ;-) ["fsf emacs" is regarded as rude by
the Emacs project, for reasons I don't fully understand.]

(if (featurep 'xemacs) ....)

rea...@newsguy.com

unread,
Jan 1, 2008, 10:47:35 AM1/1/08
to help-gn...@gnu.org
"Lennart Borgman (gmail)" <lennart...@gmail.com> writes:

> rea...@newsguy.com wrote:
>> I hope this isn't one of those things that is just plain obvious to
>> lookup in emacs but I'm striking out with M-x apropos
>>
>> How can I make emacs do something similar with if-fi constructs as it
>> does with parens?
>>
>> Even better I'd like the kind of behaviour one can get in vim with
>> parens, where not only does the syntax coloring show the other paren
>> but you can jump there with a Ctrl-%
>

> Maybe you mean %, not C-%?
>

Sorry I missed it in that first link you provided but
Turns out to be right in the emacs FAQ. I repost it here incase
people searching these forms should hit this thread.

I didn't really like the idea of turning on a whole vi like mode and I
guess a good number of others didn't either.

From the emacs FAQ

* Here is some Emacs Lisp that will make the <%> key show the
matching parenthesis, like in `vi'. In addition, if the cursor
isn't over a parenthesis, it simply inserts a % like normal.

;; By an unknown contributor

(global-set-key "%" 'match-paren)

(defun match-paren (arg)
"Go to the matching paren if on a paren; otherwise insert %."
(interactive "p")
(cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
((looking-at "\\s\)") (forward-char 1) (backward-list 1))
(t (self-insert-command (or arg 1)))))


rea...@newsguy.com

unread,
Jan 1, 2008, 10:53:34 AM1/1/08
to help-gn...@gnu.org
Alan Mackenzie <a...@muc.de> writes:

> Hi, Reader!
>
> On Mon, Dec 31, 2007 at 08:29:28PM -0600, rea...@newsguy.com wrote:
>
> [ .... ]
>
>> On a slightly different subject... if I may torture the threading
>> rules a little:
>> Speaking of portability... I'd like to get my emacs init files to be
>> more portable from one machine to the next but one I'm dealing with
>> now has different keyboard responses than most of the others and
>> requires differnt keybindings for delete-backward-char and a few
>> other things.
>
> Have a look at the "Key Bindings" in the Emacs FAQ.
>
> There are several variables you can test to find out what system you're
> running under: system-type, system-name, .... Have a look at page
> "System Interface" in the Elisp manual.

[...]

> (getenv "HOSTNAME") ; See elisp manual page "System Environment"

Another big thank you for the examples and citations of where to
look.

Xah Lee

unread,
Jan 1, 2008, 1:12:31 PM1/1/08
to
rea...@newsguy.com wrote:
「How can I make emacs do something similar with if-fi constructs as it
does with parens? 」

To match paren, you want to turn on Show Paren Mode under the Options
menu. Once the mode is on, when your cursor is on a paren, the
matching paren (or the entire enclosed text) will be highlighted, and
you can jump to it by forward-sexp.

For details on these, see:

★ Tips For Editing Lisp Code With Emacs
http://xahlee.org/emacs/emacs_editing_lisp.html

Now, the problem is to make it work for shell's if/fi syntax. Alan
Mackenzie gave suggestions how to properly implement this, but he
drivels on like a militarist sees the world.

Here's a hack that does what you want.

(defun jump-to-if-fi ()
"jump to “fi” if cursor is on word “if”, and vice versa."
(interactive)
(let (myword)
(setq myword (thing-at-point 'word))
(if (equal myword "if")
(progn
(set-mark-command nil)
(search-forward "fi")
)
(if (equal myword "fi")
(progn
(set-mark-command nil)
(search-backward "if")
)
)
)
)
)
(global-set-key (kbd "<f8>") 'jump-to-if-fi)

Xah
x...@xahlee.org
http://xahlee.org/

On Jan 1, 7:47 am, rea...@newsguy.com wrote:
> "Lennart Borgman (gmail)" <lennart.borg...@gmail.com> writes:


>
>
>
> > rea...@newsguy.com wrote:
> >> I hope this isn't one of those things that is just plain obvious to
> >> lookup in emacs but I'm striking out with M-x apropos
>
> >> How can I make emacs do something similar with if-fi constructs as it
> >> does with parens?
>
> >> Even better I'd like the kind of behaviour one can get in vim with
> >> parens, where not only does the syntax coloring show the other paren
> >> but you can jump there with a Ctrl-%
>

Alan Mackenzie

unread,
Jan 1, 2008, 2:12:05 PM1/1/08
to Xah Lee, help-gn...@gnu.org
Hi, Xah!

On Tue, Jan 01, 2008 at 10:12:31AM -0800, Xah Lee wrote:
> rea...@newsguy.com wrote:
> How can I make emacs do something similar with if-fi constructs as it
> does with parens?

[ .... ]

> Now, the problem is to make it work for shell's if/fi syntax. Alan
> Mackenzie gave suggestions how to properly implement this, but he
> drivels on like a militarist sees the world.

And a Happy New Year to you too, Xah!

> Here's a hack that does what you want.

> (defun jump-to-if-fi ()
> "jump to ?$B!Hfi?$B!I if cursor is on word ?$B!Hif?$B!I, and vice versa."


> (interactive)
> (let (myword)
> (setq myword (thing-at-point 'word))
> (if (equal myword "if")
> (progn
> (set-mark-command nil)
> (search-forward "fi")
> )
> (if (equal myword "fi")
> (progn
> (set-mark-command nil)
> (search-backward "if")
> )
> )
> )
> )
> )
> (global-set-key (kbd "<f8>") 'jump-to-if-fi)

That's fine up to a point, my dear boy, but "if"s, "while"s, and so on
nest in shell scripts. The above function thus wouldn't always find the
right "fi" or "if".

The approach is a perfectly good one and can be made to work, but it will
involve some sort of recursion, either by explicitly building a push-down
automaton, or recursively calling functions to scan over "if-fi"s and
"while-done"s.

However, this way will surely be more tedious and difficult to debug and
modify than setting text properties and using Emacs's built in syntax
table functionality.

> Xah

Mike Mattie

unread,
Jan 2, 2008, 12:00:00 AM1/2/08
to help-gn...@gnu.org
On Tue, 1 Jan 2008 15:53:04 +0000
Alan Mackenzie <a...@muc.de> wrote:

> Hi, Reader!
>
> On Mon, Dec 31, 2007 at 08:29:28PM -0600, rea...@newsguy.com wrote:
>
> [ .... ]
>
> > On a slightly different subject... if I may torture the threading
> > rules a little:
> > Speaking of portability... I'd like to get my emacs init files to
> > be more portable from one machine to the next but one I'm dealing
> > with now has different keyboard responses than most of the others
> > and requires differnt keybindings for delete-backward-char and a few
> > other things.
>
> Have a look at the "Key Bindings" in the Emacs FAQ.
>
> There are several variables you can test to find out what system
> you're running under: system-type, system-name, .... Have a look at
> page "System Interface" in the Elisp manual.
>

> > I'd like to include those in .emacs but don't know how to separate
> > them off by making them depend on which host emacs is running on.
>
> > Can you give me a push in that direction?
>
> (if (eq system-type 'gnu/linux)
> (progn
> ....)
> (...)
> ....)

(cond
;; linux
((string-equal "gnu/linux" system-type)
(load-file "/usr/share/emacs/site-lisp/site-gentoo.el"))

;; darwin
((string-equal "darwin" system-type)
(load-file (concat my-emacs-dir "darwin.el")))
)

the cond form is a bit easier to extend as the platform list grows.

> (if (eq window-system 'x) .....) ; See elisp manual page "Window
> Systems"
>
> > How to access the env variable HOSTNAME or slurp the results of
> > the hostname shell command and make the keybindings dependant on the
> > results.
>

> (getenv "HOSTNAME") ; See elisp manual page "System Environment"
>

signature.asc

rea...@newsguy.com

unread,
Jan 5, 2008, 1:33:58 PM1/5/08
to help-gn...@gnu.org
Sorry for tardy response but looking back over this thread I wanted to
thank all participants for what is a very nice discussion with many
details and suggestions. Its going into my keeper file for sure.

Stefan Monnier

unread,
Jan 9, 2008, 12:40:00 AM1/9/08
to
> So still wondering how to get paren type actions to work on if-fi type
> shell constructs.

Sadly, there is not general answer. Some modes provide special bindings
to do that. Others extend C-M-f and C-M-b to take those things
into account.
But most don't bother at all. :-(


Stefan

Arnaldo Mandel

unread,
Jan 9, 2008, 4:43:12 AM1/9/08
to help-gn...@gnu.org
On Dec 30, 2007 9:02 PM, <rea...@newsguy.com> wrote:
I hope this isn't one of those things that is just plain obvious to
lookup in emacs but I'm striking out with M-x apropos

How can I make emacs do something similar with if-fi constructs as it
does with parens?

Even better I'd like the kind of behaviour one can get in vim with
parens, where not only does the syntax coloring show the other paren
but you can jump there with a Ctrl-%

I know emacs can do that as well but not as easily.  But anyway, I use
emacs more and would like to turn its powers used in paren recognition
against the `if fi', `while done', `for done'... etc. one uses in
shell scripting.

In case I am not too late, I suggest looking at  gap-mode.el.  It was made for the GAP computer algebra system, which uses a language with this kind of syntax.
It does a good job of matching and indentation.  It does not do exactly what you want, but since the adequate matching functions are there, you can probably
get some strong leverage.

am

0 new messages