Initial commit
This commit is contained in:
commit
6970196048
|
@ -0,0 +1,6 @@
|
|||
.idea/
|
||||
dist/
|
||||
*.sh
|
||||
vendor/
|
||||
old.txt
|
||||
new.txt
|
|
@ -0,0 +1,10 @@
|
|||
# desktop
|
||||
[![GoDoc](https://godoc.org/git.sr.ht/~tslocum/desktop?status.svg)](https://godoc.org/git.sr.ht/~tslocum/desktop)
|
||||
[![builds.sr.ht status](https://builds.sr.ht/~tslocum/desktop.svg)](https://builds.sr.ht/~tslocum/desktop)
|
||||
[![Donate](https://img.shields.io/liberapay/receives/rocketnine.space.svg?logo=liberapay)](https://liberapay.com/rocketnine.space)
|
||||
|
||||
Desktop application library
|
||||
|
||||
## Warning: Experimental
|
||||
|
||||
Linux is the only supported platform. Windows support is planned.
|
|
@ -0,0 +1,37 @@
|
|||
package desktop
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func DataDirs() []string {
|
||||
var dataDirs []string
|
||||
|
||||
homeDir := os.Getenv("HOME")
|
||||
if strings.TrimSpace(homeDir) == "" {
|
||||
homeDir = "~/"
|
||||
}
|
||||
dataHomeSetting := os.Getenv("XDG_DATA_HOME")
|
||||
if dataHomeSetting == "" {
|
||||
dataHomeSetting = path.Join(homeDir, ".local/share")
|
||||
}
|
||||
dataDirs = append(dataDirs, filepath.Join(dataHomeSetting, "applications"))
|
||||
|
||||
dataDirsSetting := strings.Split(os.Getenv("XDG_DATA_DIRS"), ":")
|
||||
for _, dataDir := range dataDirsSetting {
|
||||
dataDir = strings.TrimSpace(dataDir)
|
||||
if dataDir == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
dataDirs = append(dataDirs, filepath.Join(dataDir, "applications"))
|
||||
}
|
||||
if len(dataDirs) == 1 {
|
||||
dataDirs = append(dataDirs, "/usr/local/share/applications", "/usr/share/applications")
|
||||
}
|
||||
|
||||
return dataDirs
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package desktop
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
entryHeader = []byte("[desktop entry]")
|
||||
entryName = []byte("name=")
|
||||
entryGenericName = []byte("genericname=")
|
||||
entryComment = []byte("comment=")
|
||||
entryIcon = []byte("icon=")
|
||||
entryPath = []byte("path=")
|
||||
entryExec = []byte("exec=")
|
||||
entryTerminal = []byte("terminal=true")
|
||||
entryNoDisplay = []byte("nodisplay=true")
|
||||
entryHidden = []byte("hidden=true")
|
||||
)
|
||||
|
||||
var quotes = map[string]string{
|
||||
`%%`: `%`,
|
||||
`\\\\ `: `\\ `,
|
||||
`\\\\` + "`": `\\` + "`",
|
||||
`\\\\$`: `\\$`,
|
||||
`\\\\(`: `\\(`,
|
||||
`\\\\)`: `\\)`,
|
||||
`\\\\\`: `\\\`,
|
||||
`\\\\\\\\`: `\\\\`,
|
||||
}
|
||||
|
||||
func UnquoteExec(ex string) string {
|
||||
for qs, qr := range quotes {
|
||||
ex = strings.ReplaceAll(ex, qs, qr)
|
||||
}
|
||||
|
||||
return ex
|
||||
}
|
||||
|
||||
type Entry struct {
|
||||
Name string
|
||||
GenericName string
|
||||
Comment string
|
||||
Icon string
|
||||
Path string
|
||||
Exec string
|
||||
Terminal bool
|
||||
}
|
||||
|
||||
func (e *Entry) String() string {
|
||||
name := ""
|
||||
if e.Name != "" {
|
||||
name = e.Name
|
||||
}
|
||||
if e.GenericName != "" {
|
||||
if name != "" {
|
||||
name += " / "
|
||||
}
|
||||
name += e.GenericName
|
||||
}
|
||||
|
||||
comment := "no comment"
|
||||
if e.Comment != "" {
|
||||
comment = e.Comment
|
||||
}
|
||||
|
||||
return fmt.Sprintf("{%s - %s}", name, comment)
|
||||
}
|
||||
|
||||
func (e *Entry) ExpandExec(args string) string {
|
||||
ex := e.Exec
|
||||
|
||||
ex = strings.ReplaceAll(ex, "%F", args)
|
||||
ex = strings.ReplaceAll(ex, "%f", args)
|
||||
ex = strings.ReplaceAll(ex, "%U", args)
|
||||
ex = strings.ReplaceAll(ex, "%u", args)
|
||||
|
||||
return ex
|
||||
}
|
||||
|
||||
func Parse(content io.Reader) (*Entry, error) {
|
||||
var (
|
||||
scanner = bufio.NewScanner(content)
|
||||
scannedBytes []byte
|
||||
scannedBytesLen int
|
||||
|
||||
entry = &Entry{}
|
||||
foundHeader bool
|
||||
)
|
||||
|
||||
for scanner.Scan() {
|
||||
scannedBytes = bytes.TrimSpace(scanner.Bytes())
|
||||
scannedBytesLen = len(scannedBytes)
|
||||
|
||||
if scannedBytesLen == 0 || scannedBytes[0] == byte('#') {
|
||||
continue
|
||||
} else if scannedBytes[0] == byte('[') {
|
||||
if !foundHeader {
|
||||
if scannedBytesLen < 15 || !bytes.EqualFold(scannedBytes[0:15], entryHeader) {
|
||||
return nil, errors.New("invalid desktop entry: section header not found")
|
||||
}
|
||||
|
||||
foundHeader = true
|
||||
} else {
|
||||
break // Start of new section
|
||||
}
|
||||
} else if scannedBytesLen >= 6 && bytes.EqualFold(scannedBytes[0:5], entryName) {
|
||||
entry.Name = string(scannedBytes[5:])
|
||||
} else if scannedBytesLen >= 13 && bytes.EqualFold(scannedBytes[0:12], entryGenericName) {
|
||||
entry.GenericName = string(scannedBytes[12:])
|
||||
} else if scannedBytesLen >= 9 && bytes.EqualFold(scannedBytes[0:8], entryComment) {
|
||||
entry.Comment = string(scannedBytes[8:])
|
||||
} else if scannedBytesLen >= 6 && bytes.EqualFold(scannedBytes[0:5], entryIcon) {
|
||||
entry.Icon = string(scannedBytes[5:])
|
||||
} else if scannedBytesLen >= 6 && bytes.EqualFold(scannedBytes[0:5], entryPath) {
|
||||
entry.Path = string(scannedBytes[5:])
|
||||
} else if scannedBytesLen >= 6 && bytes.EqualFold(scannedBytes[0:5], entryExec) {
|
||||
entry.Exec = UnquoteExec(string(scannedBytes[5:]))
|
||||
} else if scannedBytesLen == 13 && bytes.EqualFold(scannedBytes, entryTerminal) {
|
||||
entry.Terminal = true
|
||||
} else if (scannedBytesLen == 14 && bytes.EqualFold(scannedBytes, entryNoDisplay)) || (scannedBytesLen == 11 && bytes.EqualFold(scannedBytes, entryHidden)) {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse desktop entry")
|
||||
} else if !foundHeader {
|
||||
return nil, errors.Wrap(err, "invalid desktop entry")
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package desktop
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testData struct {
|
||||
Filename string
|
||||
Entry *Entry
|
||||
}
|
||||
|
||||
var testCases = []*testData{
|
||||
{Filename: "alacritty.desktop", Entry: &Entry{Name: "Alacritty", GenericName: "Terminal", Comment: "A cross-platform, GPU enhanced terminal emulator", Icon: "Alacritty", Path: "/home/test", Exec: "alacritty", Terminal: false}},
|
||||
{Filename: "vim.desktop", Entry: &Entry{Name: "Vim", GenericName: "Text Editor", Comment: "Edit text files", Icon: "gvim", Exec: "vim %F", Terminal: true}},
|
||||
{Filename: "nodisplay.desktop", Entry: nil},
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
for _, c := range testCases {
|
||||
expected := c.Entry
|
||||
|
||||
f, err := os.OpenFile("test/"+c.Filename, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
entry, err := Parse(f)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if entry == nil || expected == nil {
|
||||
if entry != expected {
|
||||
t.Fatalf("%s: entry incorrect: got %#v, want %#v", f.Name(), entry, expected)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if entry.Name != expected.Name {
|
||||
t.Fatalf("%s: name incorrect: got %s, want %s", f.Name(), entry.Name, expected.Name)
|
||||
}
|
||||
|
||||
if entry.GenericName != expected.GenericName {
|
||||
t.Fatalf("%s: generic name incorrect: got %s, want %s", f.Name(), entry.GenericName, expected.GenericName)
|
||||
}
|
||||
|
||||
if entry.Comment != expected.Comment {
|
||||
t.Fatalf("%s: comment incorrect: got %s, want %s", f.Name(), entry.Comment, expected.Comment)
|
||||
}
|
||||
|
||||
if entry.Icon != expected.Icon {
|
||||
t.Fatalf("%s: icon incorrect: got %s, want %s", f.Name(), entry.Icon, expected.Icon)
|
||||
}
|
||||
|
||||
if entry.Path != expected.Path {
|
||||
t.Fatalf("%s: Path incorrect: got %s, want %s", f.Name(), entry.Path, expected.Path)
|
||||
}
|
||||
|
||||
if entry.Exec != expected.Exec {
|
||||
t.Fatalf("%s: Exec incorrect: got %s, want %s", f.Name(), entry.Exec, expected.Exec)
|
||||
}
|
||||
|
||||
if entry.Terminal != expected.Terminal {
|
||||
t.Fatalf("%s: terminal incorrect: got %v, want %v", f.Name(), entry.Terminal, expected.Terminal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParse(b *testing.B) {
|
||||
var files []*os.File
|
||||
defer func() {
|
||||
for _, f := range files {
|
||||
f.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
for _, c := range testCases {
|
||||
f, err := os.OpenFile("test/"+c.Filename, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
files = append(files, f)
|
||||
}
|
||||
|
||||
b.StopTimer()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, f := range files {
|
||||
b.StartTimer()
|
||||
_, err := Parse(f)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.StopTimer()
|
||||
|
||||
_, err = f.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
module git.sr.ht/~tslocum/desktop
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/pkg/errors v0.8.1
|
|
@ -0,0 +1,2 @@
|
|||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
@ -0,0 +1,42 @@
|
|||
package desktop
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
func RunScript(ex string) (string, error) {
|
||||
runScript, err := ioutil.TempFile("", "run-*")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, err = runScript.WriteString("#!/bin/sh\n")
|
||||
if err != nil {
|
||||
runScript.Close()
|
||||
return "", err
|
||||
}
|
||||
_, err = runScript.WriteString(fmt.Sprintf("rm %s\n", runScript.Name()))
|
||||
if err != nil {
|
||||
runScript.Close()
|
||||
return "", err
|
||||
}
|
||||
_, err = runScript.WriteString("exec " + ex + "\n")
|
||||
if err != nil {
|
||||
runScript.Close()
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = runScript.Close()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = os.Chmod(runScript.Name(), 0744)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return runScript.Name(), nil
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
package desktop
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type scan struct {
|
||||
e map[int][]*Entry
|
||||
errs chan error
|
||||
in chan *scanEntry
|
||||
sync.Mutex
|
||||
sync.WaitGroup
|
||||
}
|
||||
|
||||
type scanEntry struct {
|
||||
i int
|
||||
f *os.File
|
||||
}
|
||||
|
||||
func Scan(dirs []string) (map[int][]*Entry, error) {
|
||||
s := &scan{e: make(map[int][]*Entry), errs: make(chan error), in: make(chan *scanEntry)}
|
||||
|
||||
for i := 0; i < runtime.GOMAXPROCS(-1); i++ {
|
||||
go scanner(s)
|
||||
}
|
||||
|
||||
for i, dir := range dirs {
|
||||
i, dir := i, dir
|
||||
|
||||
s.Add(1)
|
||||
go scanDir(i, dir, s)
|
||||
}
|
||||
|
||||
done := make(chan bool, 1)
|
||||
go func() {
|
||||
s.Wait()
|
||||
close(s.in)
|
||||
|
||||
done <- true
|
||||
}()
|
||||
|
||||
select {
|
||||
case err := <-s.errs:
|
||||
return nil, err
|
||||
case <-done:
|
||||
return s.e, nil
|
||||
}
|
||||
}
|
||||
|
||||
func scanner(s *scan) {
|
||||
var (
|
||||
scanEntry *scanEntry
|
||||
entry *Entry
|
||||
err error
|
||||
)
|
||||
|
||||
for scanEntry = range s.in {
|
||||
entry, err = Parse(scanEntry.f)
|
||||
scanEntry.f.Close()
|
||||
if err != nil {
|
||||
s.errs <- err
|
||||
s.Done()
|
||||
return
|
||||
} else if entry == nil {
|
||||
s.Done()
|
||||
continue
|
||||
}
|
||||
|
||||
s.Lock()
|
||||
s.e[scanEntry.i] = append(s.e[scanEntry.i], entry)
|
||||
s.Unlock()
|
||||
|
||||
s.Done()
|
||||
}
|
||||
}
|
||||
|
||||
func scanFunc(i int, s *scan) filepath.WalkFunc {
|
||||
return func(path string, f os.FileInfo, err error) error {
|
||||
s.Add(1)
|
||||
|
||||
go func() {
|
||||
if err != nil {
|
||||
s.errs <- err
|
||||
s.Done()
|
||||
return
|
||||
}
|
||||
|
||||
if f == nil || f.IsDir() || !strings.HasSuffix(strings.ToLower(path), ".desktop") {
|
||||
s.Done()
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(path, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
s.errs <- err
|
||||
s.Done()
|
||||
return
|
||||
}
|
||||
|
||||
s.in <- &scanEntry{i: i, f: f}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func scanDir(i int, dir string, s *scan) {
|
||||
defer s.Done()
|
||||
|
||||
err := filepath.Walk(dir, scanFunc(i, s))
|
||||
if err != nil {
|
||||
s.errs <- err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package desktop
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScan(t *testing.T) {
|
||||
dirs := DataDirs()
|
||||
|
||||
_, err := Scan(dirs)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkScan(b *testing.B) {
|
||||
var (
|
||||
dirs = DataDirs()
|
||||
err error
|
||||
)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err = Scan(dirs)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
TryExec=alacritty
|
||||
Path=/home/test
|
||||
Exec=alacritty
|
||||
Icon=Alacritty
|
||||
Terminal=false
|
||||
Categories=System;TerminalEmulator;
|
||||
|
||||
Name=Alacritty
|
||||
GenericName=Terminal
|
||||
Comment=A cross-platform, GPU enhanced terminal emulator
|
||||
StartupWMClass=Alacritty
|
||||
Actions=New;
|
||||
|
||||
[Desktop Action New]
|
||||
Name=New Terminal
|
||||
Exec=alacritty
|
|
@ -0,0 +1,105 @@
|
|||
# The vim.desktop file is generated by src/po/Makefile, do NOT edit.
|
||||
# Edit the src/po/vim.desktop.in file instead.
|
||||
[Desktop Entry]
|
||||
# Translators: This is the Application Name used in the Vim desktop file
|
||||
Name[de]=Vim
|
||||
Name[eo]=Vim
|
||||
Name=Vim
|
||||
# Translators: This is the Generic Application Name used in the Vim desktop file
|
||||
GenericName[de]=Texteditor
|
||||
GenericName[eo]=Tekstoredaktilo
|
||||
GenericName[ja]=テキストエディタ
|
||||
GenericName=Text Editor
|
||||
# Translators: This is the comment used in the Vim desktop file
|
||||
Comment[de]=Textdateien bearbeiten
|
||||
Comment[eo]=Redakti tekstajn dosierojn
|
||||
Comment[ja]=テキストファイルを編集します
|
||||
Comment=Edit text files
|
||||
# The translations should come from the po file. Leave them here for now, they will
|
||||
# be overwritten by the po file when generating the desktop.file.
|
||||
GenericName[da]=Teksteditor
|
||||
GenericName[pl]=Edytor tekstu
|
||||
GenericName[is]=Ritvinnsluforrit
|
||||
Comment[af]=Redigeer tekslêers
|
||||
Comment[am]=የጽሑፍ ፋይሎች ያስተካክሉ
|
||||
Comment[ar]=حرّر ملفات نصية
|
||||
Comment[az]=Mətn fayllarını redaktə edin
|
||||
Comment[be]=Рэдагаваньне тэкставых файлаў
|
||||
Comment[bg]=Редактиране на текстови файлове
|
||||
Comment[bn]=টেক্স্ট ফাইল এডিট করুন
|
||||
Comment[bs]=Izmijeni tekstualne datoteke
|
||||
Comment[ca]=Edita fitxers de text
|
||||
Comment[cs]=Úprava textových souborů
|
||||
Comment[cy]=Golygu ffeiliau testun
|
||||
Comment[da]=Rediger tekstfiler
|
||||
Comment[el]=Επεξεργασία αρχείων κειμένου
|
||||
Comment[en_CA]=Edit text files
|
||||
Comment[en_GB]=Edit text files
|
||||
Comment[es]=Edita archivos de texto
|
||||
Comment[et]=Redigeeri tekstifaile
|
||||
Comment[eu]=Editatu testu-fitxategiak
|
||||
Comment[fa]=ویرایش پروندههای متنی
|
||||
Comment[fi]=Muokkaa tekstitiedostoja
|
||||
Comment[fr]=Édite des fichiers texte
|
||||
Comment[ga]=Eagar comhad Téacs
|
||||
Comment[gu]=લખાણ ફાઇલોમાં ફેરફાર કરો
|
||||
Comment[he]=ערוך קבצי טקסט
|
||||
Comment[hi]=पाठ फ़ाइलें संपादित करें
|
||||
Comment[hr]=Uređivanje tekstualne datoteke
|
||||
Comment[hu]=Szövegfájlok szerkesztése
|
||||
Comment[id]=Edit file teks
|
||||
Comment[is]=Vinna með textaskrár
|
||||
Comment[it]=Modifica file di testo
|
||||
Comment[kn]=ಪಠ್ಯ ಕಡತಗಳನ್ನು ಸಂಪಾದಿಸು
|
||||
Comment[ko]=텍스트 파일을 편집합니다
|
||||
Comment[lt]=Redaguoti tekstines bylas
|
||||
Comment[lv]=Rediģēt teksta failus
|
||||
Comment[mk]=Уреди текстуални фајлови
|
||||
Comment[ml]=വാചക രചനകള് തിരുത്തുക
|
||||
Comment[mn]=Текст файл боловсруулах
|
||||
Comment[mr]=गद्य फाइल संपादित करा
|
||||
Comment[ms]=Edit fail teks
|
||||
Comment[nb]=Rediger tekstfiler
|
||||
Comment[ne]=पाठ फाइललाई संशोधन गर्नुहोस्
|
||||
Comment[nl]=Tekstbestanden bewerken
|
||||
Comment[nn]=Rediger tekstfiler
|
||||
Comment[no]=Rediger tekstfiler
|
||||
Comment[or]=ପାଠ୍ଯ ଫାଇଲଗୁଡ଼ିକୁ ସମ୍ପାଦନ କରନ୍ତୁ
|
||||
Comment[pa]=ਪਾਠ ਫਾਇਲਾਂ ਸੰਪਾਦਨ
|
||||
Comment[pl]=Edytuj pliki tekstowe
|
||||
Comment[pt]=Editar ficheiros de texto
|
||||
Comment[pt_BR]=Edite arquivos de texto
|
||||
Comment[ro]=Editare fişiere text
|
||||
Comment[ru]=Редактор текстовых файлов
|
||||
Comment[sk]=Úprava textových súborov
|
||||
Comment[sl]=Urejanje datotek z besedili
|
||||
Comment[sq]=Përpuno files teksti
|
||||
Comment[sr]=Измени текстуалне датотеке
|
||||
Comment[sr@Latn]=Izmeni tekstualne datoteke
|
||||
Comment[sv]=Redigera textfiler
|
||||
Comment[ta]=உரை கோப்புகளை தொகுக்கவும்
|
||||
Comment[th]=แก้ไขแฟ้มข้อความ
|
||||
Comment[tk]=Metin faýllary editle
|
||||
Comment[tr]=Metin dosyalarını düzenle
|
||||
Comment[uk]=Редактор текстових файлів
|
||||
Comment[vi]=Soạn thảo tập tin văn bản
|
||||
Comment[wa]=Asspougnî des fitchîs tecses
|
||||
Comment[zh_CN]=编辑文本文件
|
||||
Comment[zh_TW]=編輯文字檔
|
||||
TryExec=vim
|
||||
Exec=vim %F
|
||||
Terminal=true
|
||||
Type=Application
|
||||
# Translators: Search terms to find this application. Do NOT change the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords[de]=Text;Editor;
|
||||
Keywords[eo]=Teksto;redaktilo;
|
||||
Keywords[ja]=テキスト;エディタ;
|
||||
Keywords=Text;editor;
|
||||
# Translators: This is the Icon file name. Do NOT translate
|
||||
Icon[de]=gvim
|
||||
Icon[eo]=gvim
|
||||
Icon=gvim
|
||||
Categories=Utility;TextEditor;
|
||||
StartupNotify=false
|
||||
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
|
||||
NoDisplay=true
|
|
@ -0,0 +1,104 @@
|
|||
# The vim.desktop file is generated by src/po/Makefile, do NOT edit.
|
||||
# Edit the src/po/vim.desktop.in file instead.
|
||||
[Desktop Entry]
|
||||
# Translators: This is the Application Name used in the Vim desktop file
|
||||
Name[de]=Vim
|
||||
Name[eo]=Vim
|
||||
Name=Vim
|
||||
# Translators: This is the Generic Application Name used in the Vim desktop file
|
||||
GenericName[de]=Texteditor
|
||||
GenericName[eo]=Tekstoredaktilo
|
||||
GenericName[ja]=テキストエディタ
|
||||
GenericName=Text Editor
|
||||
# Translators: This is the comment used in the Vim desktop file
|
||||
Comment[de]=Textdateien bearbeiten
|
||||
Comment[eo]=Redakti tekstajn dosierojn
|
||||
Comment[ja]=テキストファイルを編集します
|
||||
Comment=Edit text files
|
||||
# The translations should come from the po file. Leave them here for now, they will
|
||||
# be overwritten by the po file when generating the desktop.file.
|
||||
GenericName[da]=Teksteditor
|
||||
GenericName[pl]=Edytor tekstu
|
||||
GenericName[is]=Ritvinnsluforrit
|
||||
Comment[af]=Redigeer tekslêers
|
||||
Comment[am]=የጽሑፍ ፋይሎች ያስተካክሉ
|
||||
Comment[ar]=حرّر ملفات نصية
|
||||
Comment[az]=Mətn fayllarını redaktə edin
|
||||
Comment[be]=Рэдагаваньне тэкставых файлаў
|
||||
Comment[bg]=Редактиране на текстови файлове
|
||||
Comment[bn]=টেক্স্ট ফাইল এডিট করুন
|
||||
Comment[bs]=Izmijeni tekstualne datoteke
|
||||
Comment[ca]=Edita fitxers de text
|
||||
Comment[cs]=Úprava textových souborů
|
||||
Comment[cy]=Golygu ffeiliau testun
|
||||
Comment[da]=Rediger tekstfiler
|
||||
Comment[el]=Επεξεργασία αρχείων κειμένου
|
||||
Comment[en_CA]=Edit text files
|
||||
Comment[en_GB]=Edit text files
|
||||
Comment[es]=Edita archivos de texto
|
||||
Comment[et]=Redigeeri tekstifaile
|
||||
Comment[eu]=Editatu testu-fitxategiak
|
||||
Comment[fa]=ویرایش پروندههای متنی
|
||||
Comment[fi]=Muokkaa tekstitiedostoja
|
||||
Comment[fr]=Édite des fichiers texte
|
||||
Comment[ga]=Eagar comhad Téacs
|
||||
Comment[gu]=લખાણ ફાઇલોમાં ફેરફાર કરો
|
||||
Comment[he]=ערוך קבצי טקסט
|
||||
Comment[hi]=पाठ फ़ाइलें संपादित करें
|
||||
Comment[hr]=Uređivanje tekstualne datoteke
|
||||
Comment[hu]=Szövegfájlok szerkesztése
|
||||
Comment[id]=Edit file teks
|
||||
Comment[is]=Vinna með textaskrár
|
||||
Comment[it]=Modifica file di testo
|
||||
Comment[kn]=ಪಠ್ಯ ಕಡತಗಳನ್ನು ಸಂಪಾದಿಸು
|
||||
Comment[ko]=텍스트 파일을 편집합니다
|
||||
Comment[lt]=Redaguoti tekstines bylas
|
||||
Comment[lv]=Rediģēt teksta failus
|
||||
Comment[mk]=Уреди текстуални фајлови
|
||||
Comment[ml]=വാചക രചനകള് തിരുത്തുക
|
||||
Comment[mn]=Текст файл боловсруулах
|
||||
Comment[mr]=गद्य फाइल संपादित करा
|
||||
Comment[ms]=Edit fail teks
|
||||
Comment[nb]=Rediger tekstfiler
|
||||
Comment[ne]=पाठ फाइललाई संशोधन गर्नुहोस्
|
||||
Comment[nl]=Tekstbestanden bewerken
|
||||
Comment[nn]=Rediger tekstfiler
|
||||
Comment[no]=Rediger tekstfiler
|
||||
Comment[or]=ପାଠ୍ଯ ଫାଇଲଗୁଡ଼ିକୁ ସମ୍ପାଦନ କରନ୍ତୁ
|
||||
Comment[pa]=ਪਾਠ ਫਾਇਲਾਂ ਸੰਪਾਦਨ
|
||||
Comment[pl]=Edytuj pliki tekstowe
|
||||
Comment[pt]=Editar ficheiros de texto
|
||||
Comment[pt_BR]=Edite arquivos de texto
|
||||
Comment[ro]=Editare fişiere text
|
||||
Comment[ru]=Редактор текстовых файлов
|
||||
Comment[sk]=Úprava textových súborov
|
||||
Comment[sl]=Urejanje datotek z besedili
|
||||
Comment[sq]=Përpuno files teksti
|
||||
Comment[sr]=Измени текстуалне датотеке
|
||||
Comment[sr@Latn]=Izmeni tekstualne datoteke
|
||||
Comment[sv]=Redigera textfiler
|
||||
Comment[ta]=உரை கோப்புகளை தொகுக்கவும்
|
||||
Comment[th]=แก้ไขแฟ้มข้อความ
|
||||
Comment[tk]=Metin faýllary editle
|
||||
Comment[tr]=Metin dosyalarını düzenle
|
||||
Comment[uk]=Редактор текстових файлів
|
||||
Comment[vi]=Soạn thảo tập tin văn bản
|
||||
Comment[wa]=Asspougnî des fitchîs tecses
|
||||
Comment[zh_CN]=编辑文本文件
|
||||
Comment[zh_TW]=編輯文字檔
|
||||
TryExec=vim
|
||||
Exec=vim %F
|
||||
Terminal=true
|
||||
Type=Application
|
||||
# Translators: Search terms to find this application. Do NOT change the semicolons! The list MUST also end with a semicolon!
|
||||
Keywords[de]=Text;Editor;
|
||||
Keywords[eo]=Teksto;redaktilo;
|
||||
Keywords[ja]=テキスト;エディタ;
|
||||
Keywords=Text;editor;
|
||||
# Translators: This is the Icon file name. Do NOT translate
|
||||
Icon[de]=gvim
|
||||
Icon[eo]=gvim
|
||||
Icon=gvim
|
||||
Categories=Utility;TextEditor;
|
||||
StartupNotify=false
|
||||
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
|
Loading…
Reference in New Issue