Уважаемый prom-net-pixel,
на вскидку могу предложить такой вариант:
Предположим у нас есть 
Memo1 и две кнопки 
Up и 
Down, тогда:
- Код: Выделить всё
- procedure TForm1.UpClick(Sender: TObject);
 var
 cp:integer;
 begin
 cp:=Memo1.SelStart-Memo1.CaretPos.X-2;
 if cp<0 then cp:=0;
 Memo1.SelStart:=cp
 end;
 
- Код: Выделить всё
- procedure TForm1.DownClick(Sender: TObject);
 var
 cp:integer;
 begin
 if Memo1.CaretPos.y<Memo1.Lines.Count then begin
 cp:=Memo1.SelStart+2+Length(Memo1.Lines[Memo1.CaretPos.y])-Memo1.CaretPos.x;
 Memo1.SelStart:=cp
 end;
 end;
 
Поясню:
У 
TMemo есть доступное только для чтения свойство 
CaretPos (собственно, будь оно Read-Write - вообще всё было бы просто) типа 
TPoint, где X - положение курсора в текущей строке, а Y - номер текущей строки. В то же самое время в 
TMemo есть свойство 
SelStart, отвечающее за, так сказать, "глобальную" позицию курсора.
Таким образом, вычтя 
CaretPos.X из 
SelStart, мы переведем курсор в начало текущей строки, а, вычтя еще и 
2 (в Linux, предполагаю, 1) - в конец предыдущей строки.
Аналогично, прибавив к SelStart разницу между длиной текущей строки и позицией курсора в ней же 
Length(Memo1.Lines[Memo1.CaretPos.y])-Memo1.CaretPos.x
, мы переведём курсор в конец текущей строки, а прибавив 2 (1) - на следующую строку.
Ну, а для полного счастья, можно в код подставить  константу (скажем, 
EoLLen) значение, которой определять с помощью директив:
- Код: Выделить всё
- const
 {$ifDef UNIX}
 EoLLen=1;
 {$EndIf}
 {$IfDef WINDOWS}
 EoLLen=2;
 {$EndIf}
 
Надеюсь, предлагаемый способ не покажется Вам излишне извращенным.
С уважением, Алексей.