Normal mode vs. insert mode vs. end of line

classic Classic list List threaded Threaded
25 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Normal mode vs. insert mode vs. end of line

Thomas-4-2
Hi,

Could somebody please tell me how I can determine if the cursor is at
the EOL position in insert mode. Let's consider the following examples
("|" = insert mode cursor, "[X]" = normal mode cursor):

#1
Some text|
:echo col('.') => 9

#2
Some tex[t]
:echo col('.') => 9

#3
Some tex|t
:echo col('.') => 9

How do I distinguish the first (or third) situation from the other two?
The problem is of course that when switching from insert mode to normal
mode both, #1 and #3, transmute into #2.

IMHO the first result should be either 10 and there should be a normal
postion 10 too (i.e. the newline character) or the third one should be
8. I use vim 6.3.80. It is of course totally possible that I'm missing
something here as I can't quite imagine that nobody has ever stumbled
over this ambiguity before. So I assume that it isn't an ambiguity for
real vim wizards?

Cheers,
Thomas.

Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

James Vega-3
On Mon, Aug 08, 2005 at 09:04:42PM +0200, Thomas wrote:

> Could somebody please tell me how I can determine if the cursor is at
> the EOL position in insert mode. Let's consider the following examples
> ("|" = insert mode cursor, "[X]" = normal mode cursor):
>
> #1
> Some text|
> :echo col('.') => 9
>
> #2
> Some tex[t]
> :echo col('.') => 9
>
> #3
> Some tex|t
> :echo col('.') => 9
>
> How do I distinguish the first (or third) situation from the other two?
> The problem is of course that when switching from insert mode to normal
> mode both, #1 and #3, transmute into #2.
If you use "<Esc>:echo col('.')" in the third situation instead of
"<C-o>:echo col('.')" here, you'll get the results you expect.  That is,
it will echo 8 instead of 9.  I'm not sure if it is intended that <C-o>
positions the cursor differently than <Esc> does.

HTH,
James
--
GPG Key: 1024D/61326D40 2003-09-02 James Vega <[hidden email]>

signature.asc (204 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

A.J.Mechelynck
In reply to this post by Thomas-4-2
----- Original Message -----
From: "Thomas" <[hidden email]>
To: <[hidden email]>
Sent: Monday, August 08, 2005 9:04 PM
Subject: Normal mode vs. insert mode vs. end of line


> Hi,
>
> Could somebody please tell me how I can determine if the cursor is at
> the EOL position in insert mode. Let's consider the following examples
> ("|" = insert mode cursor, "[X]" = normal mode cursor):
>
> #1
> Some text|
> :echo col('.') => 9
>
> #2
> Some tex[t]
> :echo col('.') => 9
>
> #3
> Some tex|t
> :echo col('.') => 9
>
> How do I distinguish the first (or third) situation from the other two?
> The problem is of course that when switching from insert mode to normal
> mode both, #1 and #3, transmute into #2.
>
> IMHO the first result should be either 10 and there should be a normal
> postion 10 too (i.e. the newline character) or the third one should be
> 8. I use vim 6.3.80. It is of course totally possible that I'm missing
> something here as I can't quite imagine that nobody has ever stumbled over
> this ambiguity before. So I assume that it isn't an ambiguity for real vim
> wizards?
>
> Cheers,
> Thomas.
>
>
>

In Insert mode, #2 and #3 above are the same (the GUI cursor is shown as a
bar on the left side of the current screen cell, the console-vim cursor
usually occupies the full width of the current cell, new characters typed in
will be inserted before the character at the cursor).

Since #1 and #3 are obviously different when you look at them (but see also
lower down), I suppose you want to distinguish them in a script. Maybe the
'virtualedit' option will help you.

If you want to distinguish between being after the last character on the
line, and being on a whitespace character at the end of the line, see
    :help 'list'
    :help 'listchars'
and in particular the "eol:" sub-option of the latter.

HTH,
Tony.


Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Steve Hall-4
In reply to this post by Thomas-4-2
From: Thomas, Aug 8, 2005 3:04 PM
>
> Could somebody please tell me how I can determine if the cursor is
> at the EOL position in insert mode.
[snip]
> It is of course totally possible that I'm missing something here as
> I can't quite imagine that nobody has ever stumbled over this
> ambiguity before.

Short answer: It is impossible with the current Vim.

Long time readers of this list will know that I have been whining
about this for years. :) Since it is only seen in insertmode, most Vim
users care little about it, but if you look at our Cream script base
you will notice tons of work arounds to try and guess the cursor
position. Email me offline and I can point out a few choice ones.

I believe this is also tied to the insertmode <C-l> bug where current
position is lost. (With :set insertmode, just alternate <C-l> and
<Esc> and watch the cursor move across your text.) Same bug seen with
<C-o> at the beginning of a line...a function can not tell if it is at
col 1 or 2.


--
Steve Hall  [ digitect mindspring com ]
:: Cream... something good to put in your Vim!
::   http://cream.sourceforge.net



Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Thomas-4-2
In reply to this post by Thomas-4-2
Hi,

Thanks for your responses. Using <esc> instead of <c-o> actually did
solve the problem in my case. I already noticed that these two act
differently but didn't realize how to make use of it. As the function
I'm calling tries to find out what is in front of the cursor it doesn't
make much sense to call it when the cursor is located before position 1
in insert mode and so using <esc> doesn't create any new problems (as
described by St.H.). The throwback is of course that vim is in normal
mode after calling the function (as I can't reliably switch back to
insert mode in the mapping) but with that I can live with.

Cheers,
Thomas.

Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Bram Moolenaar
In reply to this post by Steve Hall-4

Steve Hall wrote:

> I believe this is also tied to the insertmode <C-l> bug where current
> position is lost. (With :set insertmode, just alternate <C-l> and
> <Esc> and watch the cursor move across your text.) Same bug seen with
> <C-o> at the beginning of a line...a function can not tell if it is at
> col 1 or 2.

It's easy to make CTRL-L not move the cursor.  When I do this, won't it
break all the scripts you have that use it?  It could be called a bug
fix, but it would break existing scripts...

--
hundred-and-one symptoms of being an internet addict:
26. You check your mail. It says "no new messages." So you check it again.

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
 \\\     Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html   ///
Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Bram Moolenaar
In reply to this post by Thomas-4-2

Thomas wrote:

> Could somebody please tell me how I can determine if the cursor is at
> the EOL position in insert mode. Let's consider the following examples
> ("|" = insert mode cursor, "[X]" = normal mode cursor):
>
> #1
> Some text|
> :echo col('.') => 9
>
> #2
> Some tex[t]
> :echo col('.') => 9
>
> #3
> Some tex|t
> :echo col('.') => 9
>
> How do I distinguish the first (or third) situation from the other two?
> The problem is of course that when switching from insert mode to normal
> mode both, #1 and #3, transmute into #2.

The usual way is to first insert a character.  When using ESC the cursor
always ends up on that character.  After getting the column number you
can delete that character.

--
Anyone who is capable of getting themselves made President should on no
account be allowed to do the job.
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
 \\\     Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html   ///
Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Jürgen Krämer
In reply to this post by Thomas-4-2

Hi,

Thomas wrote:

>
> Could somebody please tell me how I can determine if the cursor is at
> the EOL position in insert mode. Let's consider the following examples
> ("|" = insert mode cursor, "[X]" = normal mode cursor):
>
> #1
> Some text|
> :echo col('.') => 9
>
> #2
> Some tex[t]
> :echo col('.') => 9
>
> #3
> Some tex|t
> :echo col('.') => 9
>
> How do I distinguish the first (or third) situation from the other two?
> The problem is of course that when switching from insert mode to normal
> mode both, #1 and #3, transmute into #2.

you can write a wrapper function which returns an empty string and call
this function by evaluating the expression register inside a map:

  function! ShowPosition()
      let column = col('.')
      let length = strlen(getline(line('.')))

      if column > length
          echo 'You are at the end of line.'
      else if column = 1
          echo 'You are in front of the first character.'
      else
          echo 'You are in front of character ' . column . ' of ' . length
      endif

      " Return an empty string, because this function must be callable from
      " insert mode without changing the text.
      return ''
  endfunction

  inoremap <F6> <c-r>ShowPosition()<cr>

By using this trick the cursor position is not changed because insert
mode is not left at all.

Regards,
J?rgen

--
J?rgen Kr?mer                              Softwareentwicklung
HABEL GmbH & Co. KG                        mailto:[hidden email]
Hinteres ?schle 2                          Tel: +49 / 74 61 / 93 53 - 15
78604 Rietheim-Weilheim                    Fax: +49 / 74 61 / 93 53 - 99
Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Steve Hall-4
In reply to this post by Bram Moolenaar
On Tue, 2005-08-09 at 11:47 +0200, Bram Moolenaar wrote:

> Steve Hall wrote:
> >
> > I believe this is also tied to the insertmode <C-l> bug where
> > current position is lost. (With :set insertmode, just alternate
> > <C-l> and <Esc> and watch the cursor move across your text.) Same
> > bug seen with <C-o> at the beginning of a line...a function can
> > not tell if it is at col 1 or 2.
>
> It's easy to make CTRL-L not move the cursor.  When I do this, won't
> it break all the scripts you have that use it?  It could be called a
> bug fix, but it would break existing scripts...

Actually, Vim 7 would be an opportune time to fix insertmode
positioning issues, script could be quite easily conditioned. Even
better, a new option could be made that turns the correcting behavior
on so that it is off by default.

Can you give me a day or two to set up a test suite that illustrates
them?

--
Steve Hall  [ digitect mindspring com ]


Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Steve Hall-4
On Tue, 2005-08-09 at 07:33 -0400, Steve Hall wrote:
>
> Actually, Vim 7 would be an opportune time to fix insertmode
> positioning issues, script could be quite easily conditioned. Even
> better, a new option could be made that turns the correcting
> behavior on so that it is off by default.
>
> Can you give me a day or two to set up a test suite that illustrates
> them?

Below displays the two related behaviors:

set nocompatible
set insertmode
set noshowmode  " just so we can see echo

function! Test1()
" insert "X" before cursor
  echo "col = " . col(".")
  normal iX
endfunction
imap <silent> <F1> <C-o>:call Test1()<CR>
imap <silent> <F2> <C-l>:call Test1()<CR><Esc>

"234567890


For the <F1> map, the function can't determine whether the cursor was
at col $ or $-1. For <F2> it's the same problem, except col 0 and 0+1.


--
Steve Hall  [ digitect mindspring com ]


Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Bram Moolenaar

Steve Hall wrote:

> On Tue, 2005-08-09 at 07:33 -0400, Steve Hall wrote:
> >
> > Actually, Vim 7 would be an opportune time to fix insertmode
> > positioning issues, script could be quite easily conditioned. Even
> > better, a new option could be made that turns the correcting
> > behavior on so that it is off by default.
> >
> > Can you give me a day or two to set up a test suite that illustrates
> > them?
>
> Below displays the two related behaviors:
>
> set nocompatible
> set insertmode
> set noshowmode  " just so we can see echo
>
> function! Test1()
> " insert "X" before cursor
>   echo "col = " . col(".")
>   normal iX
> endfunction
> imap <silent> <F1> <C-o>:call Test1()<CR>
> imap <silent> <F2> <C-l>:call Test1()<CR><Esc>
>
> "234567890
>
>
> For the <F1> map, the function can't determine whether the cursor was
> at col $ or $-1. For <F2> it's the same problem, except col 0 and 0+1.

This doesn't change when CTRL-L doesn't move the cursor, like CTRL-O
already does.  There still is the requirement that in Normal mode the
cursor can't be after the last character in the line, thus it is moved
left if it was.

The obvious solution is to insert a character before calling the
function.  But then you need CTRL-L to move cursor left, otherwise you
still don't know for sure where the cursor is.  That would actually mean
CTRL-L should remain to work as it was, so that the cursor always ends
up on the extra character.

I now think the behavior of CTRL-L should not be changed, it should do
the same thing as Esc when 'insertmode' isn't set.

Another solution would be to permit the cursor to be just after the last
character in the line.  A variant of 'virtualedit' could be used.
Disadvantage is that this means many Normal mode commands behave
different from their good old Vi way.

Another another solution would be to introduce a new Insert mode command
specifically to leave Insert mode without moving the cursor.  The cursor
would then possibily be in an illegal position until some command is
used that moves the cursor.  A bit tricky to implement, but not
impossible.

--
"Space is big.  Really big.  You just won't believe how vastly hugely mind-
bogglingly big it is.  I mean, you may think it's a long way down the
road to the chemist, but that's just peanuts to space."
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
 \\\     Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html   ///
Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Charles E Campbell Jr
In reply to this post by Steve Hall-4
Quoting Steve Hall <[hidden email]>:

> On Tue, 2005-08-09 at 07:33 -0400, Steve Hall wrote:
> >
> > Actually, Vim 7 would be an opportune time to fix insertmode
> > positioning issues...
> ...
> For the <F1> map, the function can't determine whether the cursor was
> at col $ or $-1. For <F2> it's the same problem, except col 0 and 0+1.

Seems to me that the problem is that insert mode is actually at a halfway
position; ie. in-between two actual columns.  Why not provide a new
function:  iscol(line):

  iscol('^') returns 1 if cursor is at the start of a line;
     in normal mode, that means column 1, in insert mode, column "0.5".
     returns 0 otherwise
  iscol('$') returns 0 if cursor is at the end of a line;
     in normal mode, that means col('$'), in insert mode, column $+.5.
  iscol(#) (might as well have it do something useful)
     returns 1 if there's a character at that column
     returns 0 otherwise

Guaranteed backwards compatible! :)

Regards,
Chip Campbell

Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Steve Hall-4
In reply to this post by Bram Moolenaar
On Thu, 2005-08-11 at 13:03 +0200, Bram Moolenaar wrote:
> Steve Hall wrote:
> >
[snip]
> > imap <silent> <F1> <C-o>:call Test1()<CR>
> > imap <silent> <F2> <C-l>:call Test1()<CR><Esc>
> >
> > For the <F1> map, the function can't determine whether the cursor
> > was at col $ or $-1. For <F2> it's the same problem, except col 0
> > and 0+1.
>
> This doesn't change when CTRL-L doesn't move the cursor, like CTRL-O
> already does.  

I don't understand this statement.

> There still is the requirement that in Normal mode the cursor can't
> be after the last character in the line, thus it is moved left if it
> was.

This I see. Is it possible to capture that left move somehow and
detect it within a function?

> The obvious solution is to insert a character before calling the
> function. But then you need CTRL-L to move cursor left, otherwise
> you still don't know for sure where the cursor is. That would
> actually mean CTRL-L should remain to work as it was, so that the
> cursor always ends up on the extra character.

Inserting to do logic scares me. More importantly, this would fail at
col 0 and 0+1 per above (both would insert the char at line
beginning).

> I now think the behavior of CTRL-L should not be changed, it should
> do the same thing as Esc when 'insertmode' isn't set.
>
> Another solution would be to permit the cursor to be just after the
> last character in the line. A variant of 'virtualedit' could be
> used. Disadvantage is that this means many Normal mode commands
> behave different from their good old Vi way.

Sounds disruptive. Is there any other simpler way to recover $ and $-1
after a <C-o> to call a function?

> Another another solution would be to introduce a new Insert mode
> command specifically to leave Insert mode without moving the cursor.
> The cursor would then possibily be in an illegal position until some
> command is used that moves the cursor. A bit tricky to implement,
> but not impossible.

The implementation would need to be predictable within a function. The
best situation is where the logic can disregard column. It appears
<C-o> recovers position correctly (unlike <C-l>), so determining
position relative to insert mode in a function is the bigger problem.


--
Steve Hall  [ digitect mindspring com ]


Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Steve Hall-4
In reply to this post by Charles E Campbell Jr
On Thu, 2005-08-11 at 12:27 -0700, drchip@...pbellfamily.biz wrote:
> Quoting Steve Hall <digitect@...dspring.com>:
> >
> > For the <F1> map, the function can't determine whether the cursor
> > was at col $ or $-1. For <F2> it's the same problem, except col 0
> > and 0+1.
>
> Seems to me that the problem is that insert mode is actually at a
> halfway position; ie. in-between two actual columns.  Why not
> provide a new function:  iscol(line):
[snip]

I like the decimal value, is this new in Vim 7? :)

Actually, I think the problem is more accurately between modes, that
is the position is muddled when calling a function from insertmode.
The statusline accurately reflects the current column, but the
function can't distinguish the call positions of col('$') and
col('$')-1 because of what happens on the way to normal mode.


--
Steve Hall  [ digitect mindspring com ]


Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

A.J.Mechelynck
----- Original Message -----
From: "Steve Hall" <[hidden email]>
To: <[hidden email]>
Cc: "Bram Moolenaar" <[hidden email]>; <[hidden email]>
Sent: Friday, August 12, 2005 7:39 AM
Subject: Re: Normal mode vs. insert mode vs. end of line


> On Thu, 2005-08-11 at 12:27 -0700, drchip@...pbellfamily.biz wrote:
>> Quoting Steve Hall <digitect@...dspring.com>:
>> >
>> > For the <F1> map, the function can't determine whether the cursor
>> > was at col $ or $-1. For <F2> it's the same problem, except col 0
>> > and 0+1.
>>
>> Seems to me that the problem is that insert mode is actually at a
>> halfway position; ie. in-between two actual columns.  Why not
>> provide a new function:  iscol(line):
> [snip]
>
> I like the decimal value, is this new in Vim 7? :)
>
> Actually, I think the problem is more accurately between modes, that
> is the position is muddled when calling a function from insertmode.
> The statusline accurately reflects the current column, but the
> function can't distinguish the call positions of col('$') and
> col('$')-1 because of what happens on the way to normal mode.
>
>
> --
> Steve Hall  [ digitect mindspring com ]

Just a crazy idea that went through my head: what about maintaining a
buffer-local variable holding the cursor column, as a side-effect of a
function invoked from an expression in 'statusline'?

Best regards,
Tony.


Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Bram Moolenaar
In reply to this post by Steve Hall-4

Steve Hall wrote:

> > > imap <silent> <F1> <C-o>:call Test1()<CR>
> > > imap <silent> <F2> <C-l>:call Test1()<CR><Esc>
> > >
> > > For the <F1> map, the function can't determine whether the cursor
> > > was at col $ or $-1. For <F2> it's the same problem, except col 0
> > > and 0+1.
> >
> > This doesn't change when CTRL-L doesn't move the cursor, like CTRL-O
> > already does.  
>
> I don't understand this statement.

When CTRL-L doesn't move the cursor, it will still end up on the last
character both when it was there already and when it was after the text.
Thus then you have the same problem that you don't know where it was.

> > There still is the requirement that in Normal mode the cursor can't
> > be after the last character in the line, thus it is moved left if it
> > was.
>
> This I see. Is it possible to capture that left move somehow and
> detect it within a function?

That sounds like a complicated solution.

> > The obvious solution is to insert a character before calling the
> > function. But then you need CTRL-L to move cursor left, otherwise
> > you still don't know for sure where the cursor is. That would
> > actually mean CTRL-L should remain to work as it was, so that the
> > cursor always ends up on the extra character.
>
> Inserting to do logic scares me. More importantly, this would fail at
> col 0 and 0+1 per above (both would insert the char at line
> beginning).

I don't see how this can be a problem when the line was empty.  Of
course it does require removing the character again, it messes up undo.

> > I now think the behavior of CTRL-L should not be changed, it should
> > do the same thing as Esc when 'insertmode' isn't set.
> >
> > Another solution would be to permit the cursor to be just after the
> > last character in the line. A variant of 'virtualedit' could be
> > used. Disadvantage is that this means many Normal mode commands
> > behave different from their good old Vi way.
>
> Sounds disruptive. Is there any other simpler way to recover $ and $-1
> after a <C-o> to call a function?
>
> > Another another solution would be to introduce a new Insert mode
> > command specifically to leave Insert mode without moving the cursor.
> > The cursor would then possibily be in an illegal position until some
> > command is used that moves the cursor. A bit tricky to implement,
> > but not impossible.
>
> The implementation would need to be predictable within a function. The
> best situation is where the logic can disregard column. It appears
> <C-o> recovers position correctly (unlike <C-l>), so determining
> position relative to insert mode in a function is the bigger problem.

That CTRL-O moves the cursor back to after the line is quite tricky.  It
doesn't always work.  This "the cursor was moved left a bit" flag sounds
like a complicated solution.  What if there are multi-byte characters?

I now implemented CTRL-\ CTRL-O.  It goes to Normal mode without moving
the cursor.  This means the cursor may be just after the end of the
line.  col('.') will work properly.  But we need to look out for
anything that can't handle this situation.

--
"You know, it's at times like this when I'm trapped in a Vogon airlock with
a man from Betelgeuse and about to die of asphyxiation in deep space that I
really wish I'd listened to what my mother told me when I was young!"
"Why, what did she tell you?"
"I don't know, I didn't listen!"
                -- Arthur Dent and Ford Prefect in Douglas Adams'
                   "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
 \\\     Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html   ///
Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Steve Hall-4
In reply to this post by Thomas-4-2
From: Bram Moolenaar, Aug 12, 2005 6:43 AM
> Steve Hall wrote:
>
[snip]

>
> > > The obvious solution is to insert a character before calling the
> > > function. But then you need CTRL-L to move cursor left,
> > > otherwise you still don't know for sure where the cursor is.
> > > That would actually mean CTRL-L should remain to work as it was,
> > > so that the cursor always ends up on the extra character.
> >
> > Inserting to do logic scares me. More importantly, this would fail
> > at col 0 and 0+1 per above (both would insert the char at line
> > beginning).
>
> I don't see how this can be a problem when the line was empty. Of
> course it does require removing the character again, it messes up
> undo.

Another problem is that the insertion modifies the file. Since (my)
calls are in the format

  imap <key> <C-o>:call Fun()<CR>

there's no way to capture &modified state prior to insertion.

[snip]
> That CTRL-O moves the cursor back to after the line is quite tricky.
> It doesn't always work.  This "the cursor was moved left a bit" flag
> sounds like a complicated solution.  What if there are multi-byte
> characters?
>
> I now implemented CTRL-\ CTRL-O.  It goes to Normal mode without
> moving the cursor.  This means the cursor may be just after the end
> of the line.  col('.') will work properly.  But we need to look out
> for anything that can't handle this situation.

Is this in CVS for Vim 7? I'll try to give it a whirl this weekend.


--
Steve Hall  [ digitect mindspring com ]



Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Steve Hall-4
In reply to this post by A.J.Mechelynck
On Fri, 2005-08-12 at 08:00 +0200, Tony Mechelynck wrote:
>
[snip]
>
> Just a crazy idea that went through my head: what about maintaining
> a buffer-local variable holding the cursor column, as a side-effect
> of a function invoked from an expression in 'statusline'?

Interesting thought, but as I debated on how to implement I realized
some difficulties: How could it detect not to update (and so remember
last insert mode pos) if the user had called a function? (mode()
always returns "n" in a function.) And does the cursor move just prior
to <C-o> or just after?

--
Steve Hall  [ digitect mindspring com ]


Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

A.J.Mechelynck
----- Original Message -----
From: "Steve Hall" <[hidden email]>
To: "Tony Mechelynck" <[hidden email]>
Cc: <[hidden email]>; "Bram Moolenaar" <[hidden email]>;
<[hidden email]>
Sent: Saturday, August 13, 2005 11:35 PM
Subject: Re: Normal mode vs. insert mode vs. end of line


> On Fri, 2005-08-12 at 08:00 +0200, Tony Mechelynck wrote:
>>
> [snip]
>>
>> Just a crazy idea that went through my head: what about maintaining
>> a buffer-local variable holding the cursor column, as a side-effect
>> of a function invoked from an expression in 'statusline'?
>
> Interesting thought, but as I debated on how to implement I realized
> some difficulties: How could it detect not to update (and so remember
> last insert mode pos) if the user had called a function? (mode()
> always returns "n" in a function.) And does the cursor move just prior
> to <C-o> or just after?
>
> --
> Steve Hall  [ digitect mindspring com ]

I don't know. Maybe a set of variables, in the line of ":let
b:cursor_{mode()} = col('.')" or something. Or calling a function with
col(".") and possibly mode() as parameters so it would reflect the values in
the statusline just before calling the function. The reason for the need to
call a function is that AFAIK there is no mechanism to use ":let" directly
in the 'statusline'. OK, you poke holes into the following:

    set statusline=<blabla>%{SaveCursorForMode(mode(),col(\".\"))}<blabla>
    " where <blabla> are other parts of the option, they don't concern us
here
    " for instance set stl=
    "        \%<%f\ %h%m%r%=%k[%{(&fenc==\"\")?&enc:&fenc}
    "        \%{(&bomb?\",BOM\":\"\")}]\ %-14.(%l,%c%V%)\ %P
    "        \%{SaveCursorForMode(mode(),col(\".\"))}
    " where the initial \ on each line is a continuation mark
    function! SaveCursorForMode(mode,cursor)
        let b:cursor_{a:mode} = a:cursor
        return ""
    endfunction

Best regards,
Tony.


Reply | Threaded
Open this post in threaded view
|

Re: Normal mode vs. insert mode vs. end of line

Steve Hall-4
On Sun, 2005-08-14 at 02:46 +0200, Tony Mechelynck wrote:
>
[snip]
> OK, you poke holes into the following:
>
>   set statusline=...%{SaveCursorForMode(mode(),col(\".\"))}...
[snip]
>   function! SaveCursorForMode(mode,cursor)
>     let b:cursor_{a:mode} = a:cursor
>     return ""
>   endfunction

Almost! This provides correct position at line end, hadn't been able
to do that before.

However, there is still one corner condition where it doesn't. At
virtual line end of a (second+) line that is wrapped, this technique
shows the last col *were chars to go all the way to window edge*.
Frequently lines break before that, at a space for example. The error
is the difference between the end of the last word and what I call
line width or text area, basically

  linewidth = winwidth() - [2 if signs] - &foldcolumn - [8 if &number]

Not sure how to resolve.

--
Steve Hall  [ digitect mindspring com ]


12