//ecSyntMemo.pas
      //comment this
      {
      smWordLeft:    with PrevWord(FCaretPos) do
                       CaretPos := SkipHidden(X, Y, False);
      smWordRight:   with NextWord(FCaretPos) do
                       CaretPos := SkipHidden(X, Y, True);
      }
      //add this
      smWordLeft: DoWordJump(False);
      smWordRight: DoWordJump(True);

//add this
//================
const
  sCharsSp = ' '#9;
  sCharsEOL = #10#13;
  sCharsSymb = '!"#$%&''()[]{}<>*+-/=,.:;?\^`|~';

type
  TCharGr = (cgSp, cgEOL, cgSymb, cgWord);

function TCustomSyntaxMemo.SCharGr(ch: ecChar): TCharGr;
begin
  if IsWordChar(ch) then Result:= cgWord else
   if Pos(ch, sCharsSp)>0 then Result:= cgSp else
    if Pos(ch, sCharsEOL)>0 then Result:= cgEOL else
     if Pos(ch, sCharsSymb)>0 then Result:= cgSymb else
      Result:= cgWord;
end;

procedure TCustomSyntaxMemo.DoWordJump(ANext: boolean);
var
  s: ecString;
  n: Integer;
  //------------
  procedure Next;
  var gr: TCharGr;
  begin
    if not ((n>=0) and (n<Length(s))) then Exit;
    gr:= SCharGr(s[n+1]);
    repeat Inc(n)
    until
      (n>=Length(s)) or (SCharGr(s[n+1])<>gr);
  end;
  //------------
  procedure Home;
  var gr: TCharGr;
  begin
    if not ((n>0) and (n<=Length(s))) then Exit;
    gr:= SCharGr(s[n+1]);
    while (n>0) and (SCharGr(s[n])=gr) do
      Dec(n);
  end;
begin
  begin
    s:= Lines.FText;
    n:= CaretStrPos;
    if ANext then
    begin
      Next;
      if (n<Length(s)) and (SCharGr(s[n+1])= cgSp) then
        Next;
    end
    else
    begin
      //if we at word middle, jump to word start
      if (n>0) and (SCharGr(s[n])=SCharGr(s[n+1])) then
        Home
      else
      begin
        //jump lefter, then jump to prev word start
        if (n>0) then
          begin Dec(n); Home end;
        if (n>0) and (SCharGr(s[n+1])= cgSp) then
          begin Dec(n); Home end;
      end
    end;
    CaretStrPos:= n;
  end;
end;

