Find string position given line and column location

Discussions related to Visual Prolog
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Find string position given line and column location

Unread post by Peter Muraya » 16 Feb 2015 16:04

Hi
I found the choice of attributes available from Tools/Configure Tools... rather limiting when trying to extend Visual Prolog's VDE with an external tool written in Visual Prolog. The $(line) and $(col) would be more useful if Prolog's String:: class has a predicate for converting line and column numbers in a string to a character position -- similar to the functionality provided by scilexer::findcolumn:(line, col)->position. Alternatively an attribute option such $(position) would be very helpful. Is that sensible?
Mutall Data Management Technical Support

User avatar
Thomas Linder Puls
VIP Member
Posts: 1176
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 17 Feb 2015 9:30

Position is a bit "strange" because there is a significant difference between a position in an utf-8 file and a utf-16 string. So moving to $(position) in the file will give an other result than moving to $(position) in the loaded file.

Do you intend to write a tool in Visual Prolog that should do something on the file in the editor?

What would you do if you had the position (what kind of code would you write)?
Regards Thomas Linder Puls
PDC

Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Find string position given line and column location

Unread post by Peter Muraya » 17 Feb 2015 17:47

Code: Select all

/***************************************************************************** Insert specified text at the current cursor position in the file being edited ******************************************************************************/   implement main     open core   clauses     run():-         console::init(),         /*         Retrieve the command line*/         CmdLine = mainexe::getCommandLine(),         /*         Retrive the 3 inout arguments: file, line, column and text. They are comma separated*/         Args = string::split_delimiter(CmdLine, ","),         /*         There must be 4 arguments.*/         Args == [Filename, Linestr, Colstr, Text],         /*         The line and column are integers*/         Line = toterm(Linestr),         Col = toterm(Colstr),         /*         Retrieve the text from the file*/         Instr = file::readString(Filename),         /*         Find the cursor position in the text, starting from line 1 and initial position 0. If the         $(position) attribute was available this line and its associated coding would have been not         be necessary.*/         find_position(1, Line, Col, Instr, 0)=Position,         /*         Split the input text at the requested poistion*/         string::front(Instr, Position, Part1, Part2),         /*         Insert the requested  text*/         OutStr = string::concat(Part1, Text, Part2),         /*         Save the output back to the original source file*/         file::writeString(Filename, OutStr).   /* Returns the position of a requested location (in terms of line and column position)  in the given string*/ class predicates      find_position:(integer LineCurrent, integer LineTarget, integer Col, string Text, charCount PositionIn)->charCount PositionOut. clauses      /*      We have reached the requested line, stop the search and return the requested position*/      find_position(Line, Line, Col, _Text, PositionIn)=PositionOut:-!,            /*            I'm not sure why I have to subtract 1 to get the correct results*/            PositionOut = PositionIn+Col-1.      find_position(Line, LineRef, Col, Text, PositionIn)=PositionOut:-            /*            Search for the new line separator*/            string::search(Text, "\n") =CharCount,!,            /*            If found, split the text at that position; discard the front (inlcuding the new line marker)            and continue searching using the remaining text*/            string::front(Text, CharCount+1, _Text1, Text2),            /*            Update the character count position*/            Position2 = PositionIn + CharCount+1,            /*            Continue the search. Remember to increase the line counter*/            find_position(Line+1, LineRef, Col, Text2, Position2)=PositionOut.      find_position(_Line, _LineRef, _Col, _Text, _PositionIn)=_:-            exception::raise_error("Position not found").   end implement main   goal     mainExe::run(main::run).
Mutall Data Management Technical Support

User avatar
Thomas Linder Puls
VIP Member
Posts: 1176
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 18 Feb 2015 9:53

You could also consider reading line by line:

Code: Select all

class predicates     insertAt : (string FIle, positive Line, positive Pos, string Text). clauses     insertAt(File, Line, Pos, Text) :-         I = inputStream_file::openFileUtf8(File),         % Write to a stringStream and output the entire result in the end         O = outputStream_string::new(),         % Copy first lines to output         foreach _ = std::cIterate(Line-1) do             O:write(I:readLineCRLF())         end foreach,         % Handle the interesting line         L = I:readLineCRLF(),         string::front(L, Pos-1, First, Last),         O:write(First, Text, Last),         % Copy the rest of the lines to output         foreach I:repeatToEndOfStream() do             O:write(I:readLineCRLF())         end foreach,         I:close(),         % emit the result         file::writeStringUtf8_bom(File, O:getString()).
By the way, what kind of text are you inserting so often that you want a tool for it?
Regards Thomas Linder Puls
PDC

Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Find string position given line and column location

Unread post by Peter Muraya » 18 Feb 2015 14:45

Thanks Thomas, I understand your approach.

The string I am inserting came about after adopting an approach that uses generic interfaces and classes in place of the non-generic ones. In my earlier code I had a definitions like:-

Code: Select all

interface fertilization supports reproduction end interface
After parametrization I have to change my definition to look like:-

Code: Select all

Interface fertilization_{@Vacancy, @Candidate, @Product} supports competition_{@Vacancy, @Candidate, @Product} end interface
I get tired of typing _{@Vacancy, @Candidate, @Product} which is:-
(a) fairly recurrent across many files,
(b) not amenable to search/replace even with regular expression, and
(c) problematic to type as I am using an keyboard where the keys, _{@, are not explicitly labelled.
Mutall Data Management Technical Support

User avatar
Thomas Linder Puls
VIP Member
Posts: 1176
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 18 Feb 2015 15:33

OK
Regards Thomas Linder Puls
PDC

Harrison Pratt
VIP Member
Posts: 323
Joined: 5 Nov 2000 0:01

Unread post by Harrison Pratt » 3 Apr 2017 0:47

I use M8 Spartan Clipboard Manager and find it a very helpful tool for inserting standard text clips into the IDE editor. It also can insert date & time values into pasted clips. It maintains a stack of the 20 most recent clipboard copy actions (including images) and a huge those clips can be permanently preserved as desired.

You can define a hot key combination to open up the clip selection screen (I use Ctrl-/) and paste the text.

You can define macro text expansion (for example, I defined macros such that
typing .date to paste a date string as 2017-04-02 (very handy for dating files you save)
typing .todo to paste % TODO 2017-04-02 ).

It's very useful for file headers, standard code (like database management templates), etc.

A free version is available.

http://m8software.com/clipboards/sparta ... anager.htm

Post Reply