Skip to content

Commit

Permalink
Double click on citation opens LaTeX editor (JabRef#12044)
Browse files Browse the repository at this point in the history
* First version of the double click issue

* First version to use double click to open TeXstudio

* change the click count to two

* I set the GitHub page for the test

* Replace exec() with ProcessBuilder and printStackTrace() with LOGGER

* change some useless functions

* I solve the csl-styles submodel problem

* Solve the avvrv.jabref.org conflict

* The double click function works fine for the emacs external program

* The double click function works fine for the TeXworks external program

* I changed the required code. I also delete some useless comment. I make TeXworks works for this feature

* finished texWorks and delete some comments

* delete some comments

* solve untrack files

* I make Sublime Text works for this feature

* I make WinEdt works for this feature

* delete some command and change jumpString to jumpToLineCommandlineArguments

* Fix csl-styles
  Please enter the commit message for your changes. Lines starting

* Fix abbrv.jabref.org submodules

* I make Vim works for this feature

* I rewrite jumpToLine for TexShop. But I don't hava a Mac OS machine. I hope it's working.

* Delete the JumpToLine in TeXshop and a comment line in TeXstudio

* Fix submodules (and wrong file)

* Fix empty lines

* Default should be TeXstudio

* Remvoe "Integer.format" (and add test)

* Fix PushToVim

* Cleanup PushToLyx

* Refactor PushToVim

* Add CHANGELOG.md entry

---------

Co-authored-by: Oliver Kopp <[email protected]>
  • Loading branch information
u7465990 and koppor authored Oct 23, 2024
1 parent 60e9ded commit c3e5621
Show file tree
Hide file tree
Showing 14 changed files with 188 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We added a switch not to store the linked file URL, because it caused troubles at other apps. [#11735](https://github.com/JabRef/jabref/pull/11735)
- When starting a new SLR, the selected catalogs now persist within and across JabRef sessions. [koppor#614](https://github.com/koppor/jabref/issues/614)
- We added support for drag'n'drop on an entry in the maintable to an external application to get the entry preview dropped. [#11846](https://github.com/JabRef/jabref/pull/11846)
- We added the functionality to double click on a [LaTeX citation](https://docs.jabref.org/advanced/entryeditor/latex-citations) to jump to the respective line in the LaTeX editor. [#11996](https://github.com/JabRef/jabref/issues/11996)
- We added a different background color to the search bar to indicate when the search syntax is wrong. [#11658](https://github.com/JabRef/jabref/pull/11658)
- We added a setting which always adds the literal "Cited on pages" text before each JStyle citation. [#11691](https://github.com/JabRef/jabref/pull/11732)
- We added a new plain citation parser that uses LLMs. [#11825](https://github.com/JabRef/jabref/issues/11825)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ public LatexCitationsTab(BibDatabaseContext databaseContext,

private void setSearchPane() {
progressIndicator.setMaxSize(100, 100);

citationsDisplay.basePathProperty().bindBidirectional(viewModel.directoryProperty());
citationsDisplay.setItems(viewModel.getCitationList());
citationsDisplay.setOnMouseClicked(event -> viewModel.handleMouseClick(event, citationsDisplay));

RowConstraints mainRow = new RowConstraints();
mainRow.setVgrow(Priority.ALWAYS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;

import org.jabref.gui.AbstractViewModel;
import org.jabref.gui.DialogService;
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.gui.push.PushToApplication;
import org.jabref.gui.push.PushToApplications;
import org.jabref.gui.push.PushToTeXstudio;
import org.jabref.gui.texparser.CitationsDisplay;
import org.jabref.gui.util.DirectoryDialogConfiguration;
import org.jabref.gui.util.UiTaskExecutor;
import org.jabref.logic.l10n.Localization;
Expand Down Expand Up @@ -154,6 +160,22 @@ public void onDirectoryDelete(File directory) {
};
}

public void handleMouseClick(MouseEvent event, CitationsDisplay citationsDisplay) {
Citation selectedItem = citationsDisplay.getSelectionModel().getSelectedItem();

if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2 && selectedItem != null) {
String applicationName = preferences.getPushToApplicationPreferences()
.getActiveApplicationName();
PushToApplication application = PushToApplications.getApplicationByName(
applicationName,
dialogService,
preferences)
.orElse(new PushToTeXstudio(dialogService, preferences));
preferences.getPushToApplicationPreferences().setActiveApplicationName(application.getDisplayName());
application.jumpToLine(selectedItem.path(), selectedItem.line(), selectedItem.colStart());
}
}

public void bindToEntry(BibEntry entry) {
checkAndUpdateDirectory();

Expand Down
25 changes: 25 additions & 0 deletions src/main/java/org/jabref/gui/push/AbstractPushToApplication.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jabref.gui.push;

import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;

Expand Down Expand Up @@ -181,4 +182,28 @@ public Optional<KeyBinding> getKeyBinding() {
return Optional.of(KeyBinding.PUSH_TO_APPLICATION);
}
}

public void jumpToLine(Path fileName, int line, int column) {
commandPath = preferences.getPushToApplicationPreferences().getCommandPaths().get(this.getDisplayName());

if (StringUtil.isNullOrEmpty(commandPath)) {
notDefined = true;
return;
}

String[] command = jumpToLineCommandlineArguments(fileName, line, column);
ProcessBuilder processBuilder = new ProcessBuilder();
try {
processBuilder.command(command);
processBuilder.start();
} catch (IOException excep) {
LOGGER.warn("Error: Could not call executable '{}'", commandPath, excep);
couldNotCall = true;
}
}

protected String[] jumpToLineCommandlineArguments(Path fileName, int line, int column) {
LOGGER.error("Not yet implemented");
return new String[0];
}
}
3 changes: 3 additions & 0 deletions src/main/java/org/jabref/gui/push/PushToApplication.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.jabref.gui.push;

import java.nio.file.Path;
import java.util.List;

import org.jabref.gui.actions.Action;
Expand Down Expand Up @@ -56,4 +57,6 @@ public interface PushToApplication {
PushToApplicationSettings getSettings(PushToApplication application, PushToApplicationPreferences pushToApplicationPreferences);

String getDelimiter();

void jumpToLine(Path fileName, int line, int column);
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private static String getKeyString(List<BibEntry> entries, String delimiter) {
for (BibEntry bes : entries) {
citeKey = bes.getCitationKey();
if (citeKey.isEmpty() || citeKey.get().isEmpty()) {
// Should never occur, because we made sure that all entries have keys
LOGGER.warn("Should never occur, because we made sure that all entries have keys");
continue;
}
if (first) {
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/jabref/gui/push/PushToEmacs.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -147,4 +148,9 @@ protected String getCommandName() {
public PushToApplicationSettings getSettings(PushToApplication application, PushToApplicationPreferences preferences) {
return new PushToEmacsSettings(application, dialogService, this.preferences.getFilePreferences(), preferences);
}

@Override
protected String[] jumpToLineCommandlineArguments(Path fileName, int line, int column) {
return new String[] {commandPath, "+%s".formatted(line), fileName.toString()};
}
}
5 changes: 5 additions & 0 deletions src/main/java/org/jabref/gui/push/PushToSublimeText.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,9 @@ protected String[] getCommandLine(String keyString) {
return new String[] {"sh", "-c", "\"" + commandPath + "\"" + " --command 'insert {\"characters\": \"" + citeCommand + keyString + getCiteSuffix() + "\"}'"};
}
}

@Override
protected String[] jumpToLineCommandlineArguments(Path fileName, int line, int column) {
return new String[] {commandPath, "%s:%s:%s".formatted(fileName.toString(), line, column)};
}
}
7 changes: 7 additions & 0 deletions src/main/java/org/jabref/gui/push/PushToTeXstudio.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jabref.gui.push;

import java.nio.file.Path;

import org.jabref.gui.DialogService;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.icon.JabRefIcon;
Expand Down Expand Up @@ -27,4 +29,9 @@ public JabRefIcon getApplicationIcon() {
protected String[] getCommandLine(String keyString) {
return new String[] {commandPath, "--insert-cite", "%s%s%s".formatted(getCitePrefix(), keyString, getCiteSuffix())};
}

@Override
public String[] jumpToLineCommandlineArguments(Path fileName, int line, int column) {
return new String[] {commandPath, "--line", Integer.toString(line), fileName.toString()};
}
}
8 changes: 8 additions & 0 deletions src/main/java/org/jabref/gui/push/PushToTeXworks.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jabref.gui.push;

import java.nio.file.Path;

import org.jabref.gui.DialogService;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.icon.JabRefIcon;
Expand Down Expand Up @@ -33,4 +35,10 @@ public JabRefIcon getApplicationIcon() {
protected String[] getCommandLine(String keyString) {
return new String[] {commandPath, "--insert-text", "%s%s%s".formatted(getCitePrefix(), keyString, getCiteSuffix())};
}

@Override
protected String[] jumpToLineCommandlineArguments(Path fileName, int line, int column) {
// No command known to jump to a specific line
return new String[] {commandPath, fileName.toString()};
}
}
7 changes: 7 additions & 0 deletions src/main/java/org/jabref/gui/push/PushToTexmaker.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jabref.gui.push;

import java.nio.file.Path;

import org.jabref.gui.DialogService;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.icon.JabRefIcon;
Expand Down Expand Up @@ -30,4 +32,9 @@ public JabRefIcon getApplicationIcon() {
protected String[] getCommandLine(String keyString) {
return new String[] {commandPath, "-insert", getCitePrefix() + keyString + getCiteSuffix()};
}

@Override
protected String[] jumpToLineCommandlineArguments(Path fileName, int line, int column) {
return new String[] {commandPath, "-line", Integer.toString(line), fileName.toString()};
}
}
72 changes: 64 additions & 8 deletions src/main/java/org/jabref/gui/push/PushToVim.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;

Expand All @@ -10,6 +11,7 @@
import org.jabref.gui.icon.JabRefIcon;
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.os.OS;
import org.jabref.logic.util.HeadlessExecutorService;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
Expand Down Expand Up @@ -44,14 +46,7 @@ public PushToApplicationSettings getSettings(PushToApplication application, Push

@Override
public void pushEntries(BibDatabaseContext database, List<BibEntry> entries, String keys) {
couldNotPush = false;
couldNotCall = false;
notDefined = false;

commandPath = preferences.getPushToApplicationPreferences().getCommandPaths().get(this.getDisplayName());

if ((commandPath == null) || commandPath.trim().isEmpty()) {
notDefined = true;
if (!determineCommandPath()) {
return;
}

Expand Down Expand Up @@ -105,4 +100,65 @@ public void onOperationCompleted() {
super.onOperationCompleted();
}
}

@Override
public void jumpToLine(Path fileName, int line, int column) {
if (!determineCommandPath()) {
return;
}

ProcessBuilder processBuilder = new ProcessBuilder();
try {
String[] command = jumpToLineCommandlineArguments(fileName, line, column);
if (OS.WINDOWS) {
processBuilder.command("cmd",
"/c",
"start",
"",
"\"%s\"".formatted(command[0]),
"\"%s\"".formatted(command[1]),
"\"%s\"".formatted(command[2]),
"\"+normal %s|\"".formatted(Integer.toString(column)));
} else if (OS.LINUX) {
processBuilder.command("gnome-terminal",
"--",
command[0],
command[1],
command[2],
command[3]);
} else if (OS.OS_X) {
processBuilder.command("open",
"-a",
"Terminal",
"--args",
command[0],
command[1],
command[2],
command[3]);
}
processBuilder.start();
} catch (IOException e) {
LOGGER.warn("Problem pushing to Vim.", e);
couldNotCall = true;
}
}

private boolean determineCommandPath() {
couldNotPush = false;
couldNotCall = false;
notDefined = false;

commandPath = preferences.getPushToApplicationPreferences().getCommandPaths().get(this.getDisplayName());

if ((commandPath == null) || commandPath.trim().isEmpty()) {
notDefined = true;
return false;
}
return true;
}

@Override
protected String[] jumpToLineCommandlineArguments(Path fileName, int line, int column) {
return new String[] {commandPath, "+%s".formatted(line), fileName.toString(), "+\"normal %s|\"".formatted(column)};
}
}
7 changes: 7 additions & 0 deletions src/main/java/org/jabref/gui/push/PushToWinEdt.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jabref.gui.push;

import java.nio.file.Path;

import org.jabref.gui.DialogService;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.icon.JabRefIcon;
Expand Down Expand Up @@ -28,4 +30,9 @@ protected String[] getCommandLine(String keyString) {
return new String[] {commandPath,
"\"[InsText('" + getCitePrefix() + keyString.replace("'", "''") + getCiteSuffix() + "');]\""};
}

@Override
protected String[] jumpToLineCommandlineArguments(Path fileName, int line, int column) {
return new String[] {commandPath, "\"[Open(|%s|);SelLine(%s,%s);]\"".formatted(fileName.toString(), line, column)};
}
}
30 changes: 30 additions & 0 deletions src/test/java/org/jabref/gui/push/PushToWinEdtTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.jabref.gui.push;

import java.nio.file.Path;

import org.jabref.gui.DialogService;
import org.jabref.gui.preferences.GuiPreferences;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Answers;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.mock;

class PushToWinEdtTest {

private DialogService dialogService;
private GuiPreferences preferences;

@BeforeEach
void setup() {
dialogService = mock(DialogService.class, Answers.RETURNS_DEEP_STUBS);
preferences = mock(GuiPreferences.class);
}

@Test
void jumpToLineCommandlineArguments() {
assertNotNull(new PushToWinEdt(dialogService, preferences).jumpToLineCommandlineArguments(Path.of("test.tex"), 1, 5));
}
}

0 comments on commit c3e5621

Please sign in to comment.