From fdca71d2c3d62a6077752fc367af56dacd009121 Mon Sep 17 00:00:00 2001 From: FreeSlave Date: Fri, 14 Aug 2015 12:51:48 +0300 Subject: [PATCH] Update determineTerminalEmulator. Add convenient functions to get applications paths on freedesktop --- .gitignore | 1 - README.md | 6 +-- dub.json | 4 +- dub.selections.json | 7 +++ examples/desktoptest/dub.json | 3 +- examples/desktoptest/dub.selections.json | 7 +++ examples/desktoptest/source/app.d | 7 ++- examples/desktoputil/dub.selections.json | 7 +++ examples/desktoputil/source/app.d | 2 +- source/desktopfile.d | 68 ++++++++++++++---------- 10 files changed, 73 insertions(+), 39 deletions(-) create mode 100644 dub.selections.json create mode 100644 examples/desktoptest/dub.selections.json create mode 100644 examples/desktoputil/dub.selections.json diff --git a/.gitignore b/.gitignore index 32d1160..36dfd46 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,3 @@ __dummy.html bin/ lib/ docs/ -dub.selections.json diff --git a/README.md b/README.md index 55290f6..1668df1 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,9 @@ Ddox: ### Desktop util Utility that can parse, execute and rewrites .desktop files. -This will start vlc with the first parameter set to ~/Music: +This will start vlc with the first parameter set to $HOME/Music: - dub run desktopfile:desktoputil -- exec /usr/share/applications/vlc.desktop ~/Music + dub run desktopfile:desktoputil -- exec /usr/share/applications/vlc.desktop $HOME/Music Should start command line application in terminal emulator: @@ -50,7 +50,7 @@ Starts .desktop file defined executable or opens link: Parse and write .desktop file to new location: - dub run desktopfile:desktoputil -- write /usr/share/applications/vlc.desktop ~/Desktop/vlc.desktop + dub run desktopfile:desktoputil -- write /usr/share/applications/vlc.desktop $HOME/Desktop/vlc.desktop Read basic information about desktop file: diff --git a/dub.json b/dub.json index 65f29d8..15d1540 100644 --- a/dub.json +++ b/dub.json @@ -2,9 +2,11 @@ "name": "desktopfile", "description": "Desktop Entry Specification implementation", "license" : "BSL-1.0", + "copyright": "Copyright © 2015, Roman Chistokhodov", "authors": ["Roman Chistokhodov"], "dependencies": { - "inilike": "~>0.1.1" + "inilike": "~>0.2.0", + "standardpaths": "~>0.2.0" }, "targetName" : "desktopfile", "targetPath" : "lib", diff --git a/dub.selections.json b/dub.selections.json new file mode 100644 index 0000000..3720c95 --- /dev/null +++ b/dub.selections.json @@ -0,0 +1,7 @@ +{ + "fileVersion": 1, + "versions": { + "standardpaths": "0.2.0", + "inilike": "0.2.0" + } +} \ No newline at end of file diff --git a/examples/desktoptest/dub.json b/examples/desktoptest/dub.json index c0b1c5a..9de7057 100644 --- a/examples/desktoptest/dub.json +++ b/examples/desktoptest/dub.json @@ -4,8 +4,7 @@ "copyright": "Copyright © 2015, freeslave", "authors": ["freeslave"], "dependencies": { - "desktopfile" : "*", - "standardpaths" : "~>0.1.2" + "desktopfile" : "*" }, "targetPath" : "bin", "targetType" : "executable", diff --git a/examples/desktoptest/dub.selections.json b/examples/desktoptest/dub.selections.json new file mode 100644 index 0000000..3720c95 --- /dev/null +++ b/examples/desktoptest/dub.selections.json @@ -0,0 +1,7 @@ +{ + "fileVersion": 1, + "versions": { + "standardpaths": "0.2.0", + "inilike": "0.2.0" + } +} \ No newline at end of file diff --git a/examples/desktoptest/source/app.d b/examples/desktoptest/source/app.d index c032e4a..f5b96cc 100644 --- a/examples/desktoptest/source/app.d +++ b/examples/desktoptest/source/app.d @@ -10,7 +10,7 @@ import desktopfile; string[] desktopDirs() { - return standardPaths(StandardPath.Applications) ~ writablePath(StandardPath.Desktop); + return applicationsPaths() ~ writablePath(StandardPath.Desktop); } void main(string[] args) @@ -24,6 +24,9 @@ void main(string[] args) catch(IniLikeException e) { stderr.writefln("Error reading %s: at %s: %s", entry, e.lineNumber, e.msg); } + catch(Exception e) { + stderr.writefln("Error reading %s: %s", entry, e.msg); + } } } -} \ No newline at end of file +} diff --git a/examples/desktoputil/dub.selections.json b/examples/desktoputil/dub.selections.json new file mode 100644 index 0000000..3720c95 --- /dev/null +++ b/examples/desktoputil/dub.selections.json @@ -0,0 +1,7 @@ +{ + "fileVersion": 1, + "versions": { + "standardpaths": "0.2.0", + "inilike": "0.2.0" + } +} \ No newline at end of file diff --git a/examples/desktoputil/source/app.d b/examples/desktoputil/source/app.d index 644cb55..2c408de 100644 --- a/examples/desktoputil/source/app.d +++ b/examples/desktoputil/source/app.d @@ -52,4 +52,4 @@ void main(string[] args) } else { writefln("unknown command '%s'", command); } -} \ No newline at end of file +} diff --git a/source/desktopfile.d b/source/desktopfile.d index ffddf7a..6902fde 100644 --- a/source/desktopfile.d +++ b/source/desktopfile.d @@ -2,6 +2,8 @@ * Reading, writing and executing .desktop file * Authors: * $(LINK2 https://github.com/MyLittleRobo, Roman Chistokhodov). + * Copyright: + * Roman Chistokhodov, 2015 * License: * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0). * See_Also: @@ -10,6 +12,8 @@ module desktopfile; +import standardpaths; + public import inilike; private { @@ -29,28 +33,34 @@ private { static if( __VERSION__ < 2066 ) enum nogc = 1; } -version(Posix) +/** + * Applications paths based on data paths. + * This function is available on all platforms, but requires dataPaths argument (e.g. C:\ProgramData\KDE\share on Windows) + * Returns: Array of paths, based on dataPaths with "applications" directory appended. + */ +@trusted string[] applicationsPaths(in string[] dataPaths) nothrow { + return dataPaths.map!(p => buildPath(p, "applications")).array; +} + +version(OSX) {} +else version(Posix) { - private bool isExecutable(string filePath) nothrow @trusted { - import core.sys.posix.unistd; - return access(toStringz(filePath), X_OK) == 0; + /** + * ditto, but returns paths based on known data paths. It's practically the same as standardPaths(StandardPath.applications). + * This function is defined only on freedesktop systems to avoid confusion with other systems that have data paths not compatible with Desktop Entry Spec. + */ + @trusted string[] applicationsPaths() nothrow { + return standardPaths(StandardPath.applications); } + /** - * Checks if the program exists and is executable. - * If the programPath is not an absolute path, the file is looked up in the $PATH environment variable. - * This function is defined only on Posix. - */ - bool checkTryExec(string programPath) @trusted { - if (programPath.isAbsolute()) { - return isExecutable(programPath); - } - - foreach(path; environment.get("PATH").splitter(':')) { - if (isExecutable(buildPath(path, programPath))) { - return true; - } - } - return false; + * Path where .desktop files can be stored without requiring of root privileges. + * It's practically the same as writablePath(StandardPath.applications). + * This function is defined only on freedesktop systems to avoid confusion with other systems that have data paths not compatible with Desktop Entry Spec. + * Note: it does not check if returned path exists and appears to be directory. + */ + @trusted string writableApplicationPath() nothrow { + return writablePath(StandardPath.applications); } } @@ -79,27 +89,27 @@ version(Posix) /** * Get terminal emulator. - * First, it probes $(B TERM) environment variable. If not found, checks if /usr/bin/x-terminal-emulator exists on Linux and use it on success. - * $(I xterm) is used by default, if could not determine other terminal emulator. + * It probes various alternatives in this order: x-terminal-emulator (Linux-only), xdg-terminal (Linux-only), TERM (environment variable). + * If all guesses failed, it uses xterm as fallback. * Returns: Terminal emulator command name. */ string determineTerminalEmulator() nothrow @trusted { string term; - collectException(environment.get("TERM"), term); version(linux) { if (term.empty) { - string debianTerm = "/usr/bin/x-terminal-emulator"; - if (debianTerm.isExecutable()) { - term = debianTerm; - } + term = findExecutable("x-terminal-emulator"); + } + if (term.empty) { + term = findExecutable("xdg-terminal"); } } - + if (term.empty) { + collectException(environment.get("TERM"), term); + } if (term.empty) { term = "xterm"; } - return term; } @@ -506,7 +516,7 @@ public: toReturn ~= iconStr; } } else if (token == "%c") { - toReturn ~= localizedValue("Name"); + toReturn ~= localizedValue("Name", currentLocale()); } else if (token == "%k") { toReturn ~= fileName(); } else if (token == "%d" || token == "%D" || token == "%n" || token == "%N" || token == "%m" || token == "%v") {