far2l icon indicating copy to clipboard operation
far2l copied to clipboard

How to access console output from Far Plugin?

Open faerot opened this issue 1 year ago • 20 comments

Is it possible? How?

faerot avatar Sep 17 '24 08:09 faerot

Far2 API documentation (from classic windows version) you can see in https://api.farmanager.com/ru/index.html (in Russian). far2l API changes you can see in https://github.com/elfmz/far2l/blob/master/HACKING.md

May be SaveScreen and Text from https://api.farmanager.com/ru/miscapi/index.html help you.

akruphi avatar Sep 17 '24 11:09 akruphi

@akruphi Your 1-st link is for Far3 API not Far2 @faerot I can send you Far2 Encyclopedia (contains API) in CHM format

shmuz avatar Sep 17 '24 11:09 shmuz

Far2 Encyclopedia CHM can be downloading within far2.x86.msi/far2.x64.msi from https://farmanager.com/history.php (two last links)

akruphi avatar Sep 17 '24 11:09 akruphi

Sorry, probably I was not clear enough. I am not talking about current screen of Far, I am talking about terminal output of the last command. The one that is covered by panels, SaveScreen will not help me here. Didn't find anything in the encyclopedia.

faerot avatar Sep 17 '24 14:09 faerot

Its not exposed to API anyhow for now, but can consider it. So please tell what you want to achieve to understand how its better to implement

elfmz avatar Sep 17 '24 14:09 elfmz

And may be it can be useful for you - its how console history is accessible inside far2l itself: https://github.com/elfmz/far2l/blob/master/far2l/src/vt/vtlog.h

elfmz avatar Sep 17 '24 14:09 elfmz

Its not exposed to API anyhow for now, but can consider it. So please tell what you want to achieve to understand how its better to implement

I would like to make a plugin which will scan the traceback from the console and will automatically open editor on the appropriate file, line, and column. That would be very helpful because this happens all the time when I run some script, something crashes, I scan the file name, go to the file, open it, Alt+F8, input line, etc.

faerot avatar Sep 17 '24 18:09 faerot

I assume

std::string GetAsFile(HANDLE con_hnd, bool colored, bool append_screen_lines = true);

Is what would be helpful if exposed to plugin.

faerot avatar Sep 17 '24 20:09 faerot

A much better solution is to make WinPort.h functions available to Python, just like C/C++ plugins have.

switch to user screen: self.parent.info.Control(self.hplugin, self.ffic.FCTL_GETUSERSCREEN, 0, 0)

hr = winport.GetConsoleScreenBufferInfo(...) hr = winport.ReadConsoleOutput(...)

switch back: self.parent.info.Control(self.hplugin, self.ffic.FCTL_SETUSERSCREEN, 0, 0)

m32 avatar Sep 20 '24 20:09 m32

A much better solution is to make WinPort.h functions available to Python, just like C/C++ plugins have.

switch to user screen: self.parent.info.Control(self.hplugin, self.ffic.FCTL_GETUSERSCREEN, 0, 0)

hr = winport.GetConsoleScreenBufferInfo(...) hr = winport.ReadConsoleOutput(...)

switch back: self.parent.info.Control(self.hplugin, self.ffic.FCTL_SETUSERSCREEN, 0, 0)

Will it allow to get full output - even parts that are not currently visible?

faerot avatar Sep 21 '24 07:09 faerot

unfortunately not :(, the rest is hidden in the _memories buffer

m32 avatar Sep 21 '24 08:09 m32

Wouldn't it be easier to use a decorator to catch errors?

def handle_exception(exc_type, exc_value, exc_traceback):
...

def handle_error(func):
    def __inner(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception:
            exc_type, exc_value, exc_tb = sys.exc_info()
            handle_exception(exc_type, exc_value, exc_tb)
    return __inner

@handle_error
def Open...

m32 avatar Sep 21 '24 08:09 m32

unfortunately not :(, the rest is hidden in the _memories buffer

then exposing GetAsFile is better

faerot avatar Sep 21 '24 16:09 faerot

Wouldn't it be easier to use a decorator to catch errors?

Not sure I understood you. Are you questioning the need/usefulness of the plugin which will scan traceback from console?

faerot avatar Sep 21 '24 16:09 faerot

GetAsFile is more complete and explicit, as I find getting the traceback from a variable rather than licking it from the screen

m32 avatar Sep 21 '24 20:09 m32

Getting traceback in code as you develop and scanning the crash that already happened and dumped in output are two completely different cases. Scanning traceback from output and opening in Far editor is a universal solution which works not only for your code, but for crashes in other people's code. Also it can work not just for python, but for any language that prints parse-able traceback, Node.js, etc. The parser would work not only just from output, it would also work from far viewer so you can conveniently jump from tracebacks in logs too, but scanning output stream is essential for such plugin to be useful for me.

faerot avatar Sep 21 '24 21:09 faerot

please see https://github.com/elfmz/far2l/pull/2454 - if its ok, or may be ned to add something?

elfmz avatar Oct 20 '24 18:10 elfmz

Looks fine at glance, I will try to play with it a bit later today.

faerot avatar Oct 21 '24 08:10 faerot

Either it is not working or I don't understand how to use it. I assume VTEnumBackground(NULL, 0) should return number of con handles available, but it returns 0

faerot avatar Oct 22 '24 17:10 faerot

Passing actual arguments also does nothing:

        handles = self.ffi.new('HANDLE[]', 3)
        total = self.info.FSF.VTEnumBackground(handles, 3)  # returns 0 and handles are not changed

faerot avatar Oct 22 '24 18:10 faerot

It returns count of background consoles, i.e. if you run some command in terminal and put it to background using Ctrl+Alt+Z - then you will have its handle in enumeration. For active console handle is always there and always NULL and not returned from VTEnumBackground

elfmz avatar Oct 23 '24 05:10 elfmz

Ok, figured out VTEnumBackground, works when put some tasks into the background, now VTLogExport not sure if working. This call returns False:

fn = b'/tmp/test-log'
self.info.FSF.VTLogExport(self.ffi.NULL, 0, self.ffi.new('char[]', fn))

However, when I pass buffer, Far silently crashes:

fn = self.ffi.new('char[]', 4096)
fn[0] = b'\0'
self.info.FSF.VTLogExport(self.ffi.NULL, 0, fn)

faerot avatar Oct 23 '24 07:10 faerot

@faerot try uvtlog.py in editor it inserts whole console output

m32 avatar Oct 23 '24 08:10 m32

@faerot try uvtlog.py in editor it inserts whole console output

Where can I find it?

faerot avatar Oct 23 '24 08:10 faerot

isnt your plugin '...-wide'? In such case need to use wchar_t but not char. wchar_t is 32-bit under Linux BTW

elfmz avatar Oct 23 '24 10:10 elfmz

https://github.com/elfmz/far2l/pull/2457

m32 avatar Oct 23 '24 10:10 m32

isnt your plugin '...-wide'? In such case need to use wchar_t but not char. wchar_t is 32-bit under Linux BTW

Makes sense, I was just looking at your commit changes and -mb was first, sorry. I have changed it to wchar_t and now it creates file, but the contents are empty (0 bytes)

faerot avatar Oct 23 '24 12:10 faerot

#2457

Your script does nothing for me, unfortunately.

faerot avatar Oct 23 '24 12:10 faerot

Makes sense, I was just looking at your commit changes and -mb was first, sorry. I have changed it to wchar_t and now it creates file, but the contents are empty (0 bytes)

Now set flags argument to 2 (VTH_LOGEXPORT_WITH_SCREENLINES) Without this flag it will write to log file only those lines that a 'scrolled out of screen', so in case of just started far2l - you will get empty log as without this flag its won't include what is on screen right now.

elfmz avatar Oct 23 '24 12:10 elfmz

Without this flag it will write to log file only those lines that a 'scrolled out of screen', so in case of just started far2l - you will get empty log as without this flag its won't include what is on screen right now.

By setting flags to 2 (VTH_LOGEXPORT_WITH_SCREENLINES is not available via ffic) it sort of worked, but it returned the far panels, which is not what I need. What I was expecting is the text output covered by Far panels. Is there a way to get it?

faerot avatar Oct 23 '24 12:10 faerot