From a72892b19c50769076456b918538dc6a63f3a369 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Fri, 9 Sep 2016 16:21:55 +0200 Subject: [PATCH] Add UI to export, import and reset all prefs See #262, #245, #267, #625, #802, #713. --- documentation/config-file.md | 9 +++ extension/lib/commands-frame.coffee | 3 + extension/lib/options.coffee | 50 ++++++++++++- extension/lib/prefs-bulk.coffee | 98 +++++++++++++++++++++++++ extension/lib/prefs.coffee | 4 +- extension/lib/utils.coffee | 1 + extension/lib/vim.coffee | 3 + extension/locale/de/vimfx.properties | 10 +++ extension/locale/en-US/vimfx.properties | 10 +++ extension/locale/es/vimfx.properties | 10 +++ extension/locale/fr/vimfx.properties | 10 +++ extension/locale/id/vimfx.properties | 10 +++ extension/locale/it/vimfx.properties | 10 +++ extension/locale/ja/vimfx.properties | 10 +++ extension/locale/nl/vimfx.properties | 10 +++ extension/locale/pt-BR/vimfx.properties | 10 +++ extension/locale/ru/vimfx.properties | 10 +++ extension/locale/sv-SE/vimfx.properties | 10 +++ extension/locale/zh-CN/vimfx.properties | 10 +++ extension/locale/zh-TW/vimfx.properties | 10 +++ 20 files changed, 294 insertions(+), 4 deletions(-) create mode 100644 extension/lib/prefs-bulk.coffee diff --git a/documentation/config-file.md b/documentation/config-file.md index f5886d0..0165e6a 100644 --- a/documentation/config-file.md +++ b/documentation/config-file.md @@ -121,6 +121,15 @@ vimfx.set('custom.mode.normal.zoom_in', 'zi') If you add custom commands, remember to [add shortcuts to them][custom-command-shortcuts]! +Tip: If you already have made customizations in VimFx’s settings page in the +Add-ons Manager, you can use the “Export all” button there to copy all prefs as +JSON. Paste it in your config file and either edit it, or iterate of it: + +```js +let prefs = {"hint_chars": "1234567 89"} // Pasted exported prefs. +Object.entries(prefs).forEach(([pref, value]) => vimfx.set(pref, value)) +``` + [custom-command-shortcuts]: api.md#user-content-custom-command-shortcuts diff --git a/extension/lib/commands-frame.coffee b/extension/lib/commands-frame.coffee index c5b8641..7a52db4 100644 --- a/extension/lib/commands-frame.coffee +++ b/extension/lib/commands-frame.coffee @@ -621,4 +621,7 @@ commands.collapse_selection = ({vim}) -> commands.clear_selection = ({vim}) -> utils.clearSelectionDeep(vim.content) +commands.modal = ({vim, type, args}) -> + return vim.content[type](args...) + module.exports = commands diff --git a/extension/lib/options.coffee b/extension/lib/options.coffee index d95415c..984deb8 100644 --- a/extension/lib/options.coffee +++ b/extension/lib/options.coffee @@ -21,6 +21,7 @@ defaults = require('./defaults') prefs = require('./prefs') +prefsBulk = require('./prefs-bulk') translate = require('./translate') utils = require('./utils') @@ -87,7 +88,7 @@ class Observer extends BaseObserver super({id: @vimfx.id}) injectSettings: -> - @injectInstructions() + @injectHeader() @injectOptions() @injectShortcuts() @setupKeybindings() @@ -102,7 +103,7 @@ class Observer extends BaseObserver @vimfx.goToCommand = null ) - injectInstructions: -> + injectHeader: -> setting = @appendSetting({ type: 'control' title: translate('prefs.instructions.title') @@ -115,6 +116,7 @@ class Observer extends BaseObserver ) 'first-row': 'true' }) + href = "#{@vimfx.info.homepageURL}/tree/master/documentation" docsLink = @document.createElement('label') utils.setAttributes(docsLink, { @@ -123,8 +125,17 @@ class Observer extends BaseObserver crop: 'end' class: 'text-link' }) + docsLink.style.MozBoxFlex = '1' setting.appendChild(docsLink) + for key, fn of BUTTONS + button = @document.createElement('button') + button.setAttribute('label', translate("prefs.#{key}.label")) + button.onclick = runWithVim.bind(null, @vimfx, fn) + setting.appendChild(button) + + return + injectOptions: -> for key, value of defaults.options setting = @appendSetting({ @@ -236,6 +247,41 @@ class Observer extends BaseObserver setting.setAttribute('desc', @generateErrorMessage(setting.pref)) return +resetAllPrefs = (vim) -> + vim._modal('confirm', [translate('prefs.reset.enter')], (ok) -> + return unless ok + prefsBulk.resetAll() + vim.notify(translate('prefs.reset.success')) + ) + +exportAllPrefs = (vim) -> + exported = prefsBulk.exportAll() + if Object.keys(exported).length == 0 + vim.notify(translate('prefs.export.none')) + else + utils.writeToClipboard(JSON.stringify(exported, null, 2)) + vim.notify(translate('prefs.export.success')) + +importExportedPrefs = (vim) -> + vim._modal('prompt', [translate('prefs.import.enter')], (input) -> + return if input == null or input.trim() == '' + result = prefsBulk.importExported(input.trim()) + if result.errors.length == 0 + vim.notify(translate('prefs.import.success')) + else + vim._modal('alert', [prefsBulk.createImportErrorReport(result)]) + ) + +runWithVim = (vimfx, fn) -> + return unless vim = vimfx.getCurrentVim(utils.getCurrentWindow()) + fn(vim) + +BUTTONS = { + export: exportAllPrefs + import: importExportedPrefs + reset: resetAllPrefs +} + module.exports = { observe } diff --git a/extension/lib/prefs-bulk.coffee b/extension/lib/prefs-bulk.coffee new file mode 100644 index 0000000..cd48bc1 --- /dev/null +++ b/extension/lib/prefs-bulk.coffee @@ -0,0 +1,98 @@ +### +# Copyright Simon Lydell 2016. +# +# This file is part of VimFx. +# +# VimFx is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# VimFx is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with VimFx. If not, see . +### + +# This files deals with handling all, or many, of VimFx’s prefs in bulk. + +defaults = require('./defaults') +prefs = require('./prefs') + +resetAll = -> + prefs.set(pref, null) for pref of defaults.all_prefs + return + +exportAll = -> + regular = (pref for pref of defaults.all_prefs) + custom = Services.prefs.getBranch(defaults.BRANCH).getChildList('custom.') + exported = {} + for pref in regular.concat(custom) when prefs.has(pref) + exported[pref] = prefs.get(pref) + return exported + +importExported = (exportedString) -> + exported = null + try + exported = JSON.parse(exportedString) + catch error + return { + numSuccesses: -1 + errors: [error.message] + } + + unless typeof exported == 'object' and exported != null and + Object.keys(exported).length > 0 + return { + numSuccesses: -1 + errors: ["The input must be a non-empty object. Got: #{exportedString}"] + } + + numSuccesses = 0 + errors = [] + + for pref, value of exported + unless Object::hasOwnProperty.call(defaults.all_prefs, pref) or + pref.startsWith('custom.') + errors.push("#{pref}: Unknown pref.") + continue + + try + # `prefs.set` handles validation of `value`. + prefs.set(pref, value) + catch error + errors.push("#{pref}: #{error.message.replace(/^VimFx: /, '')}") + continue + + numSuccesses += 1 + + return {numSuccesses, errors} + +createImportErrorReport = ({numSuccesses, errors}) -> + header = + if numSuccesses == -1 + 'The stuff you pasted is invalid:' + else + s1 = if numSuccesses == 1 then '' else 's' + s2 = if errors.length == 1 then '' else 's' + """ + #{numSuccesses} preference#{s1} imported successfully. + + #{errors.length} error#{s2} occurred: + """ + + return """ + #{header} + + #{errors.join('\n')} + """ + +module.exports = { + resetAll + exportAll + importExported + createImportErrorReport +} diff --git a/extension/lib/prefs.coffee b/extension/lib/prefs.coffee index 9e836bf..b29e430 100644 --- a/extension/lib/prefs.coffee +++ b/extension/lib/prefs.coffee @@ -61,8 +61,8 @@ set = (branch, key, value) -> branch.clearUserPref(key) else throw new Error( - "VimFx: Prefs may only be set to a boolean, number, string or null. - Got: #{typeof value}" + "VimFx: Preferences may only be set to a boolean, number, string or + null. Got: #{typeof value}" ) has = (branch, key) -> diff --git a/extension/lib/utils.coffee b/extension/lib/utils.coffee index f70d3c9..1e4b652 100644 --- a/extension/lib/utils.coffee +++ b/extension/lib/utils.coffee @@ -179,6 +179,7 @@ blurActiveBrowserElement = (vim) -> # those! Therefore we tell the frame script to suppress those events. {window} = vim activeElement = getActiveElement(window) + activeElement.closest('tabmodalprompt')?.abortPrompt() vim._send('browserRefocus') nextTick(window, -> activeElement.blur() diff --git a/extension/lib/vim.coffee b/extension/lib/vim.coffee index 6d339ee..87d9002 100644 --- a/extension/lib/vim.coffee +++ b/extension/lib/vim.coffee @@ -178,6 +178,9 @@ class Vim @_parent.emit('hideNotification', {vim: this}) @_statusPanel.setAttribute('inactive', 'true') + _modal: (type, args, callback = null) -> + @_run('modal', {type, args}, callback) + markPageInteraction: (value = null) -> @_send('markPageInteraction', value) _focusMarkerElement: (elementIndex, options = {}) -> diff --git a/extension/locale/de/vimfx.properties b/extension/locale/de/vimfx.properties index 7c51606..e4570b9 100644 --- a/extension/locale/de/vimfx.properties +++ b/extension/locale/de/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Nächsten Tastendruck als Text einfügen\n%S Voreinst prefs.documentation=Dokumentation +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: Ungültiger Tastendruck. error.unknown_modifier=%S: Unbekannter Modifikator: %S. Benutze nur a, c, m und s. error.duplicate_modifier=%S: Doppelter Modifikator: %S. diff --git a/extension/locale/en-US/vimfx.properties b/extension/locale/en-US/vimfx.properties index 9ded127..b4ef0a7 100644 --- a/extension/locale/en-US/vimfx.properties +++ b/extension/locale/en-US/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Insert next keypress as text\n%S Insert default\n%S R prefs.documentation=Documentation +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: Invalid key. error.unknown_modifier=%S: Unknown modifier: %S. Use only a, c, m and s. error.duplicate_modifier=%S: Duplicate modifier: %S. diff --git a/extension/locale/es/vimfx.properties b/extension/locale/es/vimfx.properties index efe08ef..f8b8c62 100644 --- a/extension/locale/es/vimfx.properties +++ b/extension/locale/es/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Insertar las próximas pulsaciones de teclado como te prefs.documentation=Documentación +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: Clave no válida. error.unknown_modifier=%S: Modificador desconocido: %S. Usar sólo a, c, m y s. error.duplicate_modifier=%S: Duplicar modificador: %S. diff --git a/extension/locale/fr/vimfx.properties b/extension/locale/fr/vimfx.properties index 31d692f..1d1f350 100644 --- a/extension/locale/fr/vimfx.properties +++ b/extension/locale/fr/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Insérer la combinaison de touches suivante comme du prefs.documentation=Documentation +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: Touche invalide. error.unknown_modifier=%S: Modificateur inconnu: %S. Utilisez seulement a, c, m et s. error.duplicate_modifier=%S: Modificateur dupliqué: %S. diff --git a/extension/locale/id/vimfx.properties b/extension/locale/id/vimfx.properties index 4c02ff5..e189243 100644 --- a/extension/locale/id/vimfx.properties +++ b/extension/locale/id/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Masukkan tekan tombol berikut sebagai teks\n%S Masukk prefs.documentation=Dokumentasi +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: Key salah. error.unknown_modifier=%S: Modifier tidak dikenali: %S. Gunakan hanya a, c, m dan s. error.duplicate_modifier=%S: Modifier sudah dipakai: %S. diff --git a/extension/locale/it/vimfx.properties b/extension/locale/it/vimfx.properties index 2d189f6..595fd28 100644 --- a/extension/locale/it/vimfx.properties +++ b/extension/locale/it/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Inserisci il prossimo carattere come testo\n%S Inseri prefs.documentation=Documentazione +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: tasto non valido. error.unknown_modifier=%S: Modificatore sconosciuto: %S. Usa solamente a, c, m ed s. error.duplicate_modifier=%S: Modificatore già utilizzato: %S. diff --git a/extension/locale/ja/vimfx.properties b/extension/locale/ja/vimfx.properties index d8b7303..68b794a 100644 --- a/extension/locale/ja/vimfx.properties +++ b/extension/locale/ja/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S 次のキー入力をテキストとして挿入\n%S prefs.documentation=ドキュメント +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: 無効なキーです。 error.unknown_modifier=%S: 不明な修飾キー: %S. a, c, m, s のみが使用できます。 error.duplicate_modifier=%S: 修飾キーが重複: %S。 diff --git a/extension/locale/nl/vimfx.properties b/extension/locale/nl/vimfx.properties index 42153f4..f15789c 100644 --- a/extension/locale/nl/vimfx.properties +++ b/extension/locale/nl/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Voer volgende toetsaanslag in als text\n%S Voer stand prefs.documentation=Documentatie +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: Ongeldige toets error.unknown_modifier=%S: Ongeldig commando: %S. Gebruik alleen a, c, m en s. error.duplicate_modifier=%S: Deze combinatie is al in gebruik: %S. diff --git a/extension/locale/pt-BR/vimfx.properties b/extension/locale/pt-BR/vimfx.properties index 40e3d30..edf833d 100644 --- a/extension/locale/pt-BR/vimfx.properties +++ b/extension/locale/pt-BR/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Inserir próximo keypress como texto\n%S Inserir padr prefs.documentation=Documentação +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: Tecla inválida. error.unknown_modifier=%S: Modificador desconhecido: %S. Use somente a, c, m e s. error.duplicate_modifier=%S: Modificador duplicado: %S. diff --git a/extension/locale/ru/vimfx.properties b/extension/locale/ru/vimfx.properties index 829d73f..4ab9dc1 100644 --- a/extension/locale/ru/vimfx.properties +++ b/extension/locale/ru/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Вставить следующее нажатие к prefs.documentation=Документация +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: Неверная клавиша. error.unknown_modifier=%S: Неизвестный модификатор: %S. Используйте только a, c, m и s. error.duplicate_modifier=%S: Дублирующийся модификатор: %S. diff --git a/extension/locale/sv-SE/vimfx.properties b/extension/locale/sv-SE/vimfx.properties index 6f867f9..3a1c27b 100644 --- a/extension/locale/sv-SE/vimfx.properties +++ b/extension/locale/sv-SE/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S Infoga nästa tangenttryckning som text\n%S Infoga st prefs.documentation=Dokumentation +prefs.reset.label=Återställ alla +prefs.reset.enter=Återställa alla VimFx-inställningar? +prefs.reset.success=Alla VimFx-inställningar återställda. +prefs.export.label=Exportera alla +prefs.export.none=Inga VimFx-inställningar att exportera. Du använder standardinställningar för allt. +prefs.export.success=Alla VimFx-inställningar kopierade till urklipp. +prefs.import.label=Importera +prefs.import.enter=Klistra in exporterade VimFx-inställningar: +prefs.import.success=Inklistrade VimFx-inställningar framgångsrikt importerade. + error.invalid_key=%S: Ogiltig tangenttryckning. error.unknown_modifier=%S: Okänd modifierare: %S. Använd endast a, c, m och s. error.duplicate_modifier=%S: Upprepad modifierare: %S. diff --git a/extension/locale/zh-CN/vimfx.properties b/extension/locale/zh-CN/vimfx.properties index 9ea4c7d..808c80f 100644 --- a/extension/locale/zh-CN/vimfx.properties +++ b/extension/locale/zh-CN/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S 将下一个按键当作文本插入 \n%S 插入默 prefs.documentation=文档 +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: 无效按键. error.unknown_modifier=%S: 未知修饰键: %S. 只能使用 a, c, m 和 s. error.duplicate_modifier=%S: 重复的修饰键: %S. diff --git a/extension/locale/zh-TW/vimfx.properties b/extension/locale/zh-TW/vimfx.properties index 8751a59..dd8756b 100644 --- a/extension/locale/zh-TW/vimfx.properties +++ b/extension/locale/zh-TW/vimfx.properties @@ -183,6 +183,16 @@ prefs.instructions.desc=%S 下一個插入按鍵當作文字\n%S 預設插入\n% prefs.documentation=說明 +prefs.reset.label=Reset all +prefs.reset.enter=Reset all VimFx preferences? +prefs.reset.success=All VimFx preferences reset. +prefs.export.label=Export all +prefs.export.none=No VimFx preferences to export. You are using the default for everything. +prefs.export.success=All VimFx preferences copied to the clipboard. +prefs.import.label=Import +prefs.import.enter=Paste exported VimFx preferences: +prefs.import.success=Pasted VimFx preferences successfully imported. + error.invalid_key=%S: 無效按鍵. error.unknown_modifier=%S: 未知的修飾鍵: %S.只能使用 a, c, m 或 s. error.duplicate_modifier=%S: 重複的修飾鍵: %S. -- 2.39.3