From 5f71e3e73ae9c0381650a922f45a241fc75a463a Mon Sep 17 00:00:00 2001 From: Trygve Aaberge Date: Fri, 28 Feb 2020 22:26:17 +0100 Subject: [PATCH] Join lines that fills the width when selecting urls Some terminal applications, like mutt and weechat, prints a newline at the end of each line even if text is wrapped. This causes urls which are wrapped to not be selectable in full. By ignoring newlines when the text fills the entire width of the screen, those urls can be selected. Many other terminal emulators do this as well. A drawback of this is that if a url happens to fill the width of the screen, the url selection will include the first word of the next line, but this doesn't happen that often so I think it's an okay tradeoff. Fixes #313 --- app/src/main/java/com/termux/app/TermuxActivity.java | 2 +- .../main/java/com/termux/terminal/TerminalBuffer.java | 11 ++++++++++- .../java/com/termux/terminal/ScreenBufferTest.java | 8 ++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/termux/app/TermuxActivity.java b/app/src/main/java/com/termux/app/TermuxActivity.java index 946d693a..12989539 100644 --- a/app/src/main/java/com/termux/app/TermuxActivity.java +++ b/app/src/main/java/com/termux/app/TermuxActivity.java @@ -757,7 +757,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection } void showUrlSelection() { - String text = getCurrentTermSession().getEmulator().getScreen().getTranscriptText(); + String text = getCurrentTermSession().getEmulator().getScreen().getTranscriptTextWithFullLinesJoined(); LinkedHashSet urlSet = extractUrls(text); if (urlSet.isEmpty()) { new AlertDialog.Builder(this).setMessage(R.string.select_url_no_found).show(); diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalBuffer.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalBuffer.java index 4e6add83..1e3af9de 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalBuffer.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalBuffer.java @@ -45,11 +45,19 @@ public final class TerminalBuffer { return getSelectedText(0, -getActiveTranscriptRows(), mColumns, mScreenRows, false).trim(); } + public String getTranscriptTextWithFullLinesJoined() { + return getSelectedText(0, -getActiveTranscriptRows(), mColumns, mScreenRows, true, true).trim(); + } + public String getSelectedText(int selX1, int selY1, int selX2, int selY2) { return getSelectedText(selX1, selY1, selX2, selY2, true); } public String getSelectedText(int selX1, int selY1, int selX2, int selY2, boolean joinBackLines) { + return getSelectedText(selX1, selY1, selX2, selY2, true, false); + } + + public String getSelectedText(int selX1, int selY1, int selX2, int selY2, boolean joinBackLines, boolean joinFullLines) { final StringBuilder builder = new StringBuilder(); final int columns = mColumns; @@ -87,7 +95,8 @@ public final class TerminalBuffer { } if (lastPrintingCharIndex != -1) builder.append(line, x1Index, lastPrintingCharIndex - x1Index + 1); - if ((!joinBackLines || !rowLineWrap) + boolean lineFillsWidth = lastPrintingCharIndex == x2Index - 1; + if ((!joinBackLines || !rowLineWrap) && (!joinFullLines || !lineFillsWidth) && row < selY2 && row < mScreenRows - 1) builder.append('\n'); } return builder.toString(); diff --git a/terminal-emulator/src/test/java/com/termux/terminal/ScreenBufferTest.java b/terminal-emulator/src/test/java/com/termux/terminal/ScreenBufferTest.java index 08de2905..23942bf5 100644 --- a/terminal-emulator/src/test/java/com/termux/terminal/ScreenBufferTest.java +++ b/terminal-emulator/src/test/java/com/termux/terminal/ScreenBufferTest.java @@ -37,4 +37,12 @@ public class ScreenBufferTest extends TerminalTestCase { withTerminalSized(5, 3).enterString("ABCDE\r\nFGHIJ").assertLinesAre("ABCDE", "FGHIJ", " "); assertEquals("ABCDE\nFG", mTerminal.getSelectedText(0, 0, 1, 1)); } + + public void testGetSelectedTextJoinFullLines() { + withTerminalSized(5, 3).enterString("ABCDE\r\nFG"); + assertEquals("ABCDEFG", mTerminal.getScreen().getSelectedText(0, 0, 1, 1, true, true)); + + withTerminalSized(5, 3).enterString("ABC\r\nFG"); + assertEquals("ABC\nFG", mTerminal.getScreen().getSelectedText(0, 0, 1, 1, true, true)); + } }