/****************************** Module Header ******************************* * * Module Name: swaptext.e * * Copyright (c) Netlabs EPM Distribution Project 2002 * * $Id$ * * =========================================================================== * * This file is part of the Netlabs EPM Distribution package and is free * software. You can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * Netlabs EPM Distribution. This library is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * ****************************************************************************/ ; --------------------------------------------------------------------------- defc MoveLineUp if .last < 2 then return endif SavedAutosave = .autosave .autosave = 0 call psave_mark( SavedMark) call NextCmdAltersText() getfileid fid Line = Max( .line - 1, 1) call pset_mark( .line, .line, 1, MAXCOL, 'LINE', fid) -- The destination for line mark movement is below the current line. -- Therefore go one more line up. .lineg = Line - 1 -- Go to line Line - 1 without scrolling --call pmove_mark() movemark .lineg = Line -- Go to line Line without scrolling .line = Line -- Scroll when outside of window call prestore_mark( SavedMark) .autosave = SavedAutosave return ; --------------------------------------------------------------------------- defc MoveLineDown if .last < 2 then return endif SavedAutosave = .autosave .autosave = 0 call psave_mark( SavedMark) call NextCmdAltersText() getfileid fid Line = Min( .line + 1, .last) call pset_mark( .line, .line, 1, MAXCOL, 'LINE', fid) .lineg = Line -- Go to line Line without scrolling --call pmove_mark() movemark .lineg = Line -- Go to line Line without scrolling .line = Line -- Scroll when outside of window call prestore_mark( SavedMark) .autosave = SavedAutosave return ; --------------------------------------------------------------------------- defc MoveCharLeft SavedAutosave = .autosave .autosave = 0 call psave_mark( SavedMark) call NextCmdAltersText() getfileid fid call pset_mark( .line, .line, .col, .col, 'CHAR', fid) OldCol = .col left if .col < OldCol then movemark endif call prestore_mark( SavedMark) .autosave = SavedAutosave return ; --------------------------------------------------------------------------- defc MoveCharRight SavedAutosave = .autosave .autosave = 0 call psave_mark( SavedMark) call NextCmdAltersText() getfileid fid call pset_mark( .line, .line, .col, .col, 'CHAR', fid) OldCol = .col right right if .col > OldCol then movemark endif call prestore_mark( SavedMark) .autosave = SavedAutosave return ; --------------------------------------------------------------------------- defc MoveExpressionRight SeparatorList = arg( 1) call MoveExpr( 'R', arg( 1)) ; --------------------------------------------------------------------------- defc MoveExpressionLeft SeparatorList = arg( 1) call MoveExpr( 'L', arg( 1)) ; --------------------------------------------------------------------------- ; Process mark under cursor, if suitable for a move expression action, ; otherwise process expression under cursor. Literals are recognized and ; entire literals are handled as expressions. Beneath the seperators, there ; exist conditional separators, that are handled as normal strings, if no ; separator follows. defproc MoveExpr Direction = upcase( arg( 1)) if not wordpos( Direction, 'R L') then Direction = 'R' endif SepList = arg( 2) if SepList = '' then SepList = ' ~`!%^&*()+=][{}|;?/><'\t endif -- CondSepList: These chars are handled as separators, if another -- normal separator or the line end follows. CondSepList = '-\.:,''"' getfileid fid getmark firstline, lastline, firstcol, lastcol, markfid -- If mark under cursor is char or block and only on one line, take that -- instead of expression under cursor. fProcessMark = MarkIsExpression() SavedAutosave = .autosave .autosave = 0 call psave_mark( SavedMark) -- unmarks call NextCmdAltersText() do once = 1 to 1 getline LineStr CursorCol = .col LineLen = length( LineStr) RevLineStr = reverse( LineStr) pStart = CursorCol FoundLiteralPos = FindLiteralPos( LineStr, pStart) -- If mark exists under cursor, get marked string if fProcessMark then pBegin1 = firstcol pEnd1 = lastcol -- If enquoted, get enquoted string elseif FoundLiteralPos <> '0 0' then parse value FoundLiteralPos with pBegin1 pEnd1 -- Find first expression ---------------------------------------------- else -- Check if cursor is on a sep. or on a cond. sep. that is followed -- by a sep. pStart = CursorCol fStop = 0 do forever p = pos( substr( LineStr, pStart, 1), SepList) if p > 0 then --dprintf( 'On a separator, move cursor to an expression first.') fStop = 1 leave endif p = pos( substr( LineStr, pStart, 1), CondSepList) if p > 0 then pStart = pStart + 1 iterate endif leave enddo if fStop then leave endif -- Find end of expression 1 -- Verify 'M' returns the first sep char after the expression pStart = CursorCol pEnd1 = verify( LineStr, SepList, 'M', pStart) if pEnd1 = 0 then pEnd1 = LineLen else -- Sep. found, set end pos. pEnd1 = pEnd1 - 1 endif -- Strip trailing conditional separators from expression 1 do forever if pEnd1 < 1 then leave endif p = pos( substr( LineStr, pEnd1, 1), CondSepList) if p > 0 then -- Cond. sep. found, reduce end pos. pEnd1 = pEnd1 - 1 iterate else leave endif enddo -- Find start of expression 1 pRevStart = LineLen - CursorCol + 1 -- Verify 'M' returns the first sep char after the expression pRevEnd1 = verify( RevLineStr, SepList, 'M', pRevStart) if pRevEnd1 = 0 then pBegin1 = 1 else pBegin1 = LineLen - pRevEnd1 + 2 endif endif ----------------------------------------------------------------- -- Get expression 1 Len1 = pEnd1 - pBegin1 + 1 Expr1 = substr( LineStr, pBegin1, Len1) -- Mark expression 1 call pset_mark( .line, .line, pBegin1, pEnd1, 'CHAR', fid) -- Find next expression right ----------------------------------------- if Direction = 'R' then -- Use first sep after Expr1 as pStart -- Verify 'M' returns the first sep char after the expression pStart = verify( LineStr, SepList, 'M', pEnd1) if pStart = 0 then 'SayError No second expression right from cursor found.' leave endif -- Verify 'N' returns the first non-sep char after the expression pBegin2 = verify( LineStr, SepList''CondSepList, 'N', pStart) if pBegin2 = 0 then 'SayError No second expression right from cursor found.' leave endif -- If enquoted, get enquoted string pStart = pBegin2 FoundPos = FindLiteralPos( LineStr, pStart) if FoundPos <> '0 0' then parse value FoundPos with pBegin2 pEnd2 else -- Find end of expression 2 -- Verify 'M' returns the first sep char after the expression pStart = pBegin2 pEnd2 = verify( LineStr, SepList, 'M', pStart) if pEnd2 = 0 then pEnd2 = LineLen else -- Sep. found, set end pos. pEnd2 = pEnd2 - 1 endif -- Strip trailing conditional separators from expression 2 do forever if pEnd2 < 1 then leave endif p = pos( substr( LineStr, pEnd2, 1), CondSepList) if p > 0 then -- Cond. sep. found, reduce end pos. pEnd2 = pEnd2 - 1 iterate else leave endif enddo endif -- Get expression 2 Len2 = pEnd2 - pBegin2 + 1 Expr2 = substr( LineStr, pBegin2, Len2) if Expr2 = '' then leave endif -- Move expression 1 .col = pBegin2 movemark -- Mark expression 2 call pset_mark( .line, .line, pBegin2, pEnd2, 'CHAR', fid) -- Move expression 2 .col = pBegin1 movemark -- Restore mark and col if fProcessMark then call pset_mark( .line, .line, pBegin2 - Len1 + Len2, pBegin2 + Len2 - 1, 'CHAR', fid) endif .col = pEnd2 + CursorCol - pEnd1 -- Find next expression left ------------------------------------------ else -- Find end of expression 2 -- Use sep before Expr1 as pStart pRevStart = LineLen - pBegin1 + 2 -- This skips also trailing conditional separators -- Verify 'N' returns the first non-sep char after the expression pRevBegin2 = verify( RevLineStr, SepList''CondSepList, 'N', pRevStart) if pRevBegin2 = 0 then 'SayError No second expression left from cursor found.' leave endif pEnd2 = LineLen - pRevBegin2 + 1 -- If enquoted, get enquoted string pStart = pEnd2 FoundPos = FindLiteralPos( LineStr, pStart) if FoundPos <> '0 0' then parse value FoundPos with pBegin2 pEnd2 else -- Find start of expression 2 pRevStart = LineLen - pEnd2 + 1 -- Verify 'M' returns the first sep char after the expression pRevEnd2 = verify( RevLineStr, SepList, 'M', pRevStart) if pRevEnd2 = 0 then pBegin2 = 1 else pBegin2 = LineLen - pRevEnd2 + 2 endif endif -- Get expression 2 Len2 = pEnd2 - pBegin2 + 1 Expr2 = substr( LineStr, pBegin2, Len2) if Expr2 = '' then leave endif -- Move expression 1 .col = pBegin2 movemark -- Mark expression 2 call pset_mark( .line, .line, pBegin2 + Len1, pEnd2 + Len1, 'CHAR', fid) -- Move expression 2 .col = pBegin1 + Len1 movemark -- Restore mark and col if fProcessMark then call pset_mark( .line, .line, pBegin2, pBegin2 + Len1 - 1, 'CHAR', fid) endif .col = pBegin2 + CursorCol - pBegin1 endif ----------------------------------------------------------------- enddo if not fProcessMark then call prestore_mark( SavedMark) endif .autosave = SavedAutosave return