Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom link matchers to be registered in terminal API #18454

Closed
dbaeumer opened this issue Jan 12, 2017 · 18 comments
Closed

Allow custom link matchers to be registered in terminal API #18454

dbaeumer opened this issue Jan 12, 2017 · 18 comments
Assignees
Labels
api feature-request Request for new features or functionality *out-of-scope Posted issue is not in scope of VS Code terminal Integrated terminal issues
Milestone

Comments

@dbaeumer
Copy link
Member

  • VSCode Version: 1.9.x

Another cool feature would be to have link detection in the terminal so that users can navigate the output. Since link detection can be very specific to the command executed it might best come from the creator of a ITerminalInstance. An implementation idea would be:

  • the client listens to ITerminalInstance.onData (the line based version propsed in another issue)
  • marks links be line
@dbaeumer dbaeumer added the terminal Integrated terminal issues label Jan 12, 2017
@dbaeumer
Copy link
Member Author

@isidorn FYI.

@isidorn
Copy link
Contributor

isidorn commented Jan 12, 2017

Would also be awesome if I could reuse this link detection logic in the debug world since I have a bunch of feature requests for improving link detection in the REPL

@Tyriar
Copy link
Member

Tyriar commented Jan 12, 2017

This needs to be in xterm.js due to the sensitivity and also the amount of DOM manipulation there. I put out a proposal on the project for how we could do this the other day. xtermjs/xterm.js#455

@Tyriar
Copy link
Member

Tyriar commented Jan 24, 2017

I'll likely be working on this in February. @dbaeumer @isidorn I want the plain terminal to have reasonable link detection (#7321), do you think you will need the ability to explicitly register link patterns if xterm.js always tries to match common link patterns?

You can read my proposed solution here xtermjs/xterm.js#455

@Tyriar Tyriar added this to the February 2017 milestone Jan 24, 2017
@Tyriar Tyriar added the api label Jan 24, 2017
@dbaeumer
Copy link
Member Author

I think I would need to provide these patterns. For the task execution what users want is to click on the file part of a problem and open the file in the editor. Since the problem matcher of a task matches the file part as well I would need to communicate the matching part to the xterm to ensure the same patterns are used.

@kieferrm kieferrm mentioned this issue Feb 6, 2017
38 tasks
Tyriar added a commit that referenced this issue Feb 15, 2017
@Tyriar
Copy link
Member

Tyriar commented Feb 15, 2017

@dbaeumer I've exposed the xterm.js functions on ITerminalInstance so you can register/deregister your own links now:

const matcherId = terminalInstance.registerLinkMatcher(/abc/, console.log, 0)

@Tyriar Tyriar added the feature-request Request for new features or functionality label Feb 15, 2017
@Tyriar
Copy link
Member

Tyriar commented Feb 15, 2017

As for exposing on the API, we can wrap the return number in a Disposable that would call deregisterLinkMatcher on dispose.

export interface Terminal {
	/**
	 * Registers a link matcher on the terminal, enabling custom links to be created and handled.
	 * @param regex The regular expression to search within a row for, specifically this searches
	 * the textContent of the row. Note that you will need to use \s to match a space ' ' character.
	 * @param callback The callback that is triggered when the link is triggered.
	 * @param matchIndex The index of the link from the regex.match(text) call. This defaults to 0
	 * (for regular expressions without capture groups).
	 * @return A disposable which removes the link matcher from the terminal.
	 */
	registerLinkMatcher(regex: RegExp, callback: (url: string) => void, matchIndex?: number): Disposable;
}

@jrieken any feedback would be appreciated 😃

@dbaeumer
Copy link
Member Author

@Tyriar thanks. Will look into how to best integrate this.

@jrieken
Copy link
Member

jrieken commented Feb 15, 2017

hm... we are generally not doing this things on instances but global, like registerDocumentLinkProvider. So, I would opt for something that globally. Then I wonder if that API is maybe a little too specific. Is it that the terminal wants to collect all regexp's and apply them by itself? Is that a technical limitation? Could we have something like a terminal line reader which would then also enable someone to find links without a regex but by some other means?

Also, wrt the callback? We usually don't play it that way but just use uris and let the system handle them. It's not that want to do something outside of normal link handling right?

@Tyriar
Copy link
Member

Tyriar commented Feb 15, 2017

The reason for it not being global is because the main use case for this is the tasks framework, which will conditionally register link handlers based on the task running. Conditional registration is because link matchers will only be valid under certain tasks (for example tasks that are run on a directory may not fully quality the file).

There is a line reader as well but for performance reasons you can only add lines using this, the regex will only check rows that haven't updated in 200ms. The proposed api is very similar to the upstream api (which I'm also proposing) that will handle everything, that however needs to be a generic callback function.

The issue with using a Uri as the handler is that the link is whatever you clicked, this could be something like 'tsconfig.json' in the case of some tasks which isn't a valid Uri as it needs more context. This could however be a function to map the link match to a Uri. @dbaeumer am I right here as your use case is the one we need to cover?

@jrieken
Copy link
Member

jrieken commented Feb 15, 2017

The reason for it not being global is because the main use case for this is the tasks framework,

We should not build API if we only have a single use-case. Question for other use-cases which might drive this API in another direction:

  • Image the azure command line prints references to remote log files, like az list-log prints names of log files of the last n hours. Should this API support detection of such names and opening of these logs (with a registered content provider)?
  • Should generic link detection, like http-links, be implemented with this?
  • Can I write an extension that listen for ls and turns its output into file-links?

@Tyriar
Copy link
Member

Tyriar commented Feb 15, 2017

Great questions!

TL;DR

  • Web link matchers are always on by default
  • Let's explore making terminals more knowledgeable about where the output is coming from before allowing custom links in the API Command aware terminals #20676

Should generic link detection, like http-links, be implemented with this?

This is always on (and in Insiders now), you can override this detection by using regex that matches that row. For example /google/ will override the regular link detection for google since only one link matcher will go off on a single row).

Should this API support detection of such names and opening of these logs (with a registered content provider)?

This would be possible under the tasks framework, or if the commands were triggered via extensions. The issue here is each individual row has no context as to what process/cwd generated the text.

Can I write an extension that listen for ls and turns its output into file-links?

Yes in conjunction with ITerminalInstance.onData which tasks will also need (#18453), if you know the form of the prompt then yes:

terminal.onData(row => {
  if (row.match(/$ ls\n/)) {
    //registerLinkMatcher(...)
  }
});

// Dispose the link matcher when the new prompt is seen

So, I would opt for something that globally.

How the link matchers are scoped is an interesting thought. The reason they're not global right now is because very specific link matchers like an ls matcher for example is only relevant when ls is run. This leads me to think maybe there could be something we could do to improve the terminal's awareness of what it's actually running. I created #20676 to explore a possible improvement that could be made here.

I also proposed a change in xtermjs/xterm.js#538 (comment) that would register link matchers on a per-row basis but having per-row and global would probably make sense to save memory. The http link matcher for example would be global which would save (<row count>-1)*<reference size> memory.

@Tyriar Tyriar changed the title ITerminalInstance support for link detection Allow custom link matchers to be registered in terminal API Feb 15, 2017
@Spown
Copy link

Spown commented Apr 5, 2017

maybe before making a custom, all-purpose matchers you could first "hardcode" a simple :line:col and (line,col) detection and the ability to jump to a character?

@Tyriar
Copy link
Member

Tyriar commented Apr 5, 2017

@Spown that's captured in #21472

@michallepicki
Copy link

michallepicki commented May 14, 2018

@Tyriar I would love to get (file path):line (without column) and (file path):line:optional_text working (optional_text usually begins with a space, supporting this will do I guess) as these are printed by Elixir language stacktraces. I could look at previous PRs and contribute, but is there any chance this would this be merged?

EDIT: so I looked at #25331 and it says that (file path):line should be supported, but it doesn't work on a simple test:

echo "test/file/path.exs:20"

Is that a regression? I can file a new issue.

EDIT2:
OHH I get it now, the file paths which are being printed need to be relative to the workspace root and not to the current bash directory. Welp, that's annoying...

@Tyriar
Copy link
Member

Tyriar commented May 14, 2018

@michaelchiche yeah there's another issue for following the cwd

@Tyriar Tyriar added the *out-of-scope Posted issue is not in scope of VS Code label Jun 21, 2018
@vscodebot
Copy link

vscodebot bot commented Jun 21, 2018

This issue is being closed to keep the number of issues in our inbox on a manageable level, we are closing issues that have been on the backlog for a long time but have not gained traction: We look at the number of votes the issue has received and the number of duplicate issues filed. If you disagree and feel that this issue is crucial: We are happy to listen and to reconsider.

If you wonder what we are up to, please see our roadmap and issue reporting guidelines.

Thanks for your understanding and happy coding!

@vscodebot vscodebot bot closed this as completed Jun 21, 2018
@Tyriar
Copy link
Member

Tyriar commented Jun 21, 2018

Out of scope since tasks is not an extension.

@vscodebot vscodebot bot locked and limited conversation to collaborators Aug 5, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api feature-request Request for new features or functionality *out-of-scope Posted issue is not in scope of VS Code terminal Integrated terminal issues
Projects
None yet
Development

No branches or pull requests

6 participants