Terminal: hyper link mode: handle relative paths better
* We were trying relative paths as is, which means checking them with Terminal's current working directory. Now we use the CWD of the active process. * In case the path is relative, add a context menu item "Copy absolute path".
This commit is contained in:
parent
7daf375812
commit
a15966b3b0
@ -30,6 +30,7 @@
|
||||
#include <UTF8.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "ActiveProcessInfo.h"
|
||||
#include "Shell.h"
|
||||
#include "TermConst.h"
|
||||
#include "TerminalBuffer.h"
|
||||
@ -52,6 +53,7 @@ static const uint32 kAutoScroll = 'AScr';
|
||||
|
||||
static const uint32 kMessageOpenLink = 'OLnk';
|
||||
static const uint32 kMessageCopyLink = 'CLnk';
|
||||
static const uint32 kMessageCopyAbsolutePath = 'CAbs';
|
||||
static const uint32 kMessageMenuClosed = 'MClo';
|
||||
|
||||
|
||||
@ -638,6 +640,7 @@ TermView::HyperLinkState::HyperLinkState(TermView* view)
|
||||
fURLCharClassifier(kURLAdditionalWordCharacters),
|
||||
fPathComponentCharClassifier(
|
||||
BString(kDefaultAdditionalWordCharacters).RemoveFirst("/")),
|
||||
fCurrentDirectory(),
|
||||
fHighlight(),
|
||||
fHighlightActive(false)
|
||||
{
|
||||
@ -648,6 +651,12 @@ TermView::HyperLinkState::HyperLinkState(TermView* view)
|
||||
void
|
||||
TermView::HyperLinkState::Entered()
|
||||
{
|
||||
ActiveProcessInfo activeProcessInfo;
|
||||
if (fView->GetActiveProcessInfo(activeProcessInfo))
|
||||
fCurrentDirectory = activeProcessInfo.CurrentDirectory();
|
||||
else
|
||||
fCurrentDirectory.Truncate(0);
|
||||
|
||||
_UpdateHighlight();
|
||||
}
|
||||
|
||||
@ -792,9 +801,9 @@ TermView::HyperLinkState::_GetHyperLinkAt(BPoint where, bool pathPrefixOnly,
|
||||
return false;
|
||||
|
||||
// check, whether the file exists
|
||||
struct stat st;
|
||||
if (lstat(text, &st) == 0) {
|
||||
_link = HyperLink(text, HyperLink::TYPE_PATH);
|
||||
BString actualPath;
|
||||
if (_EntryExists(text, actualPath)) {
|
||||
_link = HyperLink(text, actualPath, HyperLink::TYPE_PATH);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -813,8 +822,8 @@ TermView::HyperLinkState::_GetHyperLinkAt(BPoint where, bool pathPrefixOnly,
|
||||
if (!textBuffer->PreviousLinePos(_end))
|
||||
return false;
|
||||
|
||||
if (lstat(text, &st) == 0) {
|
||||
_link = HyperLink(text, HyperLink::TYPE_PATH);
|
||||
if (_EntryExists(text, actualPath)) {
|
||||
_link = HyperLink(text, actualPath, HyperLink::TYPE_PATH);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -832,8 +841,10 @@ TermView::HyperLinkState::_GetHyperLinkAt(BPoint where, bool pathPrefixOnly,
|
||||
return false;
|
||||
|
||||
path.Truncate(colonIndex);
|
||||
if (lstat(path, &st) == 0) {
|
||||
_link = HyperLink(text,
|
||||
if (_EntryExists(path, actualPath)) {
|
||||
BString address = path == actualPath
|
||||
? text : BString(fCurrentDirectory) << '/' << text;
|
||||
_link = HyperLink(text, address,
|
||||
i == 0
|
||||
? HyperLink::TYPE_PATH_WITH_LINE
|
||||
: HyperLink::TYPE_PATH_WITH_LINE_AND_COLUMN);
|
||||
@ -845,6 +856,25 @@ TermView::HyperLinkState::_GetHyperLinkAt(BPoint where, bool pathPrefixOnly,
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TermView::HyperLinkState::_EntryExists(const BString& path,
|
||||
BString& _actualPath) const
|
||||
{
|
||||
if (path.IsEmpty())
|
||||
return false;
|
||||
|
||||
if (path[0] == '/' || fCurrentDirectory.IsEmpty()) {
|
||||
_actualPath = path;
|
||||
} else {
|
||||
_actualPath.Truncate(0);
|
||||
_actualPath << fCurrentDirectory << '/' << path;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
return lstat(_actualPath, &st) == 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TermView::HyperLinkState::_UpdateHighlight()
|
||||
{
|
||||
@ -947,9 +977,12 @@ TermView::HyperLinkMenuState::Prepare(BPoint point, const HyperLink& link)
|
||||
case HyperLink::TYPE_PATH:
|
||||
case HyperLink::TYPE_PATH_WITH_LINE:
|
||||
case HyperLink::TYPE_PATH_WITH_LINE_AND_COLUMN:
|
||||
menuBuilder
|
||||
.AddItem(B_TRANSLATE("Open path"), kMessageOpenLink)
|
||||
.AddItem(B_TRANSLATE("Copy path"), kMessageCopyLink);
|
||||
menuBuilder.AddItem(B_TRANSLATE("Open path"), kMessageOpenLink);
|
||||
menuBuilder.AddItem(B_TRANSLATE("Copy path"), kMessageCopyLink);
|
||||
if (fLink.Text() != fLink.Address()) {
|
||||
menuBuilder.AddItem(B_TRANSLATE("Copy absolute path"),
|
||||
kMessageCopyAbsolutePath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
menu->SetTargetForItems(fView);
|
||||
@ -974,22 +1007,27 @@ TermView::HyperLinkMenuState::MessageReceived(BMessage* message)
|
||||
return true;
|
||||
|
||||
case kMessageCopyLink:
|
||||
case kMessageCopyAbsolutePath:
|
||||
{
|
||||
if (fLink.IsValid()) {
|
||||
BString toCopy = message->what == kMessageCopyLink
|
||||
? fLink.Text() : fLink.Address();
|
||||
|
||||
if (!be_clipboard->Lock())
|
||||
return true;
|
||||
|
||||
be_clipboard->Clear();
|
||||
|
||||
if (BMessage *data = be_clipboard->Data()) {
|
||||
data->AddData("text/plain", B_MIME_TYPE,
|
||||
fLink.Address().String(),
|
||||
fLink.Address().Length());
|
||||
data->AddData("text/plain", B_MIME_TYPE, toCopy.String(),
|
||||
toCopy.Length());
|
||||
be_clipboard->Commit();
|
||||
}
|
||||
|
||||
be_clipboard->Unlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case kMessageMenuClosed:
|
||||
fView->_NextState(fView->fDefaultState);
|
||||
|
@ -132,6 +132,8 @@ private:
|
||||
bool _GetHyperLinkAt(BPoint where,
|
||||
bool pathPrefixOnly, HyperLink& _link,
|
||||
TermPos& _start, TermPos& _end);
|
||||
bool _EntryExists(const BString& path,
|
||||
BString& _actualPath) const;
|
||||
|
||||
void _UpdateHighlight();
|
||||
void _UpdateHighlight(BPoint where, int32 modifiers);
|
||||
@ -142,6 +144,7 @@ private:
|
||||
private:
|
||||
DefaultCharClassifier fURLCharClassifier;
|
||||
DefaultCharClassifier fPathComponentCharClassifier;
|
||||
BString fCurrentDirectory;
|
||||
TermViewHighlight fHighlight;
|
||||
bool fHighlightActive;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user