Эффективное редактирование вики-текстов — плагин CodeEditor

From Wiki4Intranet
Jump to: navigation, search
This wikilog article is a draft, it was not published yet.
Line 14: Line 14:
  
 
Осталось чуть настроить его, чтобы было удобней русскоязычным пользователям MediaWiki (да, без этого будет не оч)
 
Осталось чуть настроить его, чтобы было удобней русскоязычным пользователям MediaWiki (да, без этого будет не оч)
* отключить ругань на русские буквы
+
* отключить ругань на русские буквы (чортовы «ambigious characters»)
 
* отключить сраный minimap (как я его ненавижу, отключать в каждой новой инсталляции VS Code)
 
* отключить сраный minimap (как я его ненавижу, отключать в каждой новой инсталляции VS Code)
 
* включить wordwrap
 
* включить wordwrap
Line 21: Line 21:
 
Скопируйте в настройки экстеншна (moz-extension://9007abec-06c1-4fbe-9dbe-f03ea790271a/view/options.html, в «Default Context») — проще скопировать все, чем обьяснять, что там поменял.
 
Скопируйте в настройки экстеншна (moz-extension://9007abec-06c1-4fbe-9dbe-f03ea790271a/view/options.html, в «Default Context») — проще скопировать все, чем обьяснять, что там поменял.
 
{{:code-editor-firefox-default-context-for-mediawiki}}
 
{{:code-editor-firefox-default-context-for-mediawiki}}
 +
 +
Ну и при редактировании длинной статьи в наших виках, делайте так:
 +
* время от времени нажимайте на кнопку «Save» в окне Code-Editor — это еще будет не сохранение статьи, а сохранение в textarea вкладки с открытой на редактирование статьей.
 +
* а вот в этой вкладке, нажмите на нашу доработку — кнопку «Опубликовать» — т.е. без выхода из режима редактирования выобновите статью
 +
* и ее можно превьювить в какой-нибудь другой открытой вкладке — и все это без выхода из режима редактирования без потери контекста где вы находитесь и т.п.
 +
* если эти вкладки в FF запинить первыми, там можно переключаться между ними с помощью хоткеев «ALT-1», … «ALT-9».

Revision as of 05:22, 17 April 2024

Вики-статьи, с их возможностью включений, шаблонов, макросов отлично подходят для формирования целостной, самособираемой технической документации по различным проектам. Ведь альтернативы:

  • Офисные форматы с слабыми возможностями включения документов (OpenOffice, Word) — не дотягивают по гибкости.
  • SGML Docbook — было неплохо для 90ых, но протухло и сдохло.
  • LaTeX — неплохо, но наследие ужасной разметки и слабая генерация html-контента — не то.
  • Pandoc-стек с Markdown — очень перспективно, но до сих пор нет стандарта на включение документов (куча фильтров, у каждого свои проблемы).

Основные проблемы написания технических документов с вики-системами и вообще любыми веб-CMS — не очень удобно использовать стандартную textare для разметки, хочется заюзать все пространство вкладки браузера, и возможности нормального редактора, типа VS Code. Есть всякие такие интеграторы с VS Code, но все-таки не особо удобно, отдельно VS Code с его мешаниной вкладок, отдельно броузер с его вкладками, особенно когда редактируешь кучу документов — надо бы чтобы это было встроено в броузер, чтобы как-то рулить ими («Tree Style Tab» — почему еще не все с этим живут?).

Для последний версий MediaWiki уже есть https://www.mediawiki.org/wiki/Extension:CodeEditor — очень похоже на то что надо, но наша сборка пока еще (все сил нет обновлять) на замороженных старых версиях MediaWiki, наверно не сработает.

С другой стороны, а почему бы не поставить экстенш прямо в броузер? Собственно более умные редакторы textarea всегда были тем, что хотелось опытным пользователям (сам в нулевых писал на первом механизме FF extensionнов интеграцию с notepad++…), и вот, есть расширение https://addons.mozilla.org/en-US/firefox/addon/code-editor/ , которое затаскивает «почти VS Code» (ну вернее «Monaco Editor», на котором он основан), прямо в Firefox.

Осталось чуть настроить его, чтобы было удобней русскоязычным пользователям MediaWiki (да, без этого будет не оч)

  • отключить ругань на русские буквы (чортовы «ambigious characters»)
  • отключить сраный minimap (как я его ненавижу, отключать в каждой новой инсталляции VS Code)
  • включить wordwrap


Скопируйте в настройки экстеншна (moz-extension://9007abec-06c1-4fbe-9dbe-f03ea790271a/view/options.html, в «Default Context») — проще скопировать все, чем обьяснять, что там поменял.

/**
 * @type {Context}
 */
({
    /**
     * {@link https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneEditorConstructionOptions.html}
     * {@link https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneDiffEditorConstructionOptions.html}
     */
    options: {
        minimap: {
            enabled: false,
        },
        unicodeHighlight: {
            ambiguousCharacters: false,
            invisibleCharacters: false,
        },        
        lineNumbers: "off",
        theme: "wiki-theme",
        language: "wikitext",
        wordWrap: "on",
        accessibilitySupport: "on",
        accessibilityPageSize: 20,
        scrollBeyondLastLine: true,
        ignoreTrimWhitespace: true,
        useInlineViewWhenSpaceIsLimited: true,
    },
    /**
     * {@link https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IActionDescriptor.html}
     */
    actions: {
        "user.toggleWordWarp": {
            label: "Toggle Word Wrap",
            keybindings: [
                "Alt+KeyZ",
            ],
            contextMenuGroupId: "view",
            contextMenuOrder: 4.5,
            run(editor) {
                let wrappingInfo = editor.getOption(monaco.editor.EditorOption.wrappingInfo);
                editor.updateOptions({
                    wordWrapOverride2: wrappingInfo.wrappingColumn == -1 ? 'on' : 'off',
                });
            },
        },
        "user.toggleIgnoreTrimWhitespace": {
            label: "Toggle Show Trim Whitespace Diff",
            precondition: "isInDiffEditor",
            contextMenuGroupId: "view",
            contextMenuOrder: 4.6,
            run() {
                let editor = editorUtil.editor;
                let value = editor._options?.ignoreTrimWhitespace?.value;
                editor.updateOptions({
                    ignoreTrimWhitespace: !value,
                });
            },
        },
    },
    init: [
        {
            func() {
                monaco.languages.register({ id: 'wikitext' });
                monaco.languages.setMonarchTokensProvider("wikitext", {
                    tokenizer: {
                        root: [
                            [/'''[^']+'''/, "bold-quote"],
                        ],
                        whitespace: [
                            [/[ \t\r\n]+/, 'white'],
                            [/<!--/, 'comment', '@comment']
                        ],
                        comment: [
                            [/[^<\-]+/, 'comment.content'],
                            [/-->/, 'comment', '@pop'],
                            [/<!--/, 'comment.content.invalid'],
                            [/[<\-]/, 'comment.content']
                        ],
 
                    },
                });
                // Define a new theme that contains only rules that match this language
                monaco.editor.defineTheme("wiki-theme", {
                    base: "vs",
                    inherit: true,
                    rules: [
                        { token: "bold-quote", foreground: "008800", fontStyle: "bold"  },
                    ],
                    colors: {
                        "editor.foreground": "#000000",
                    },
                });
 
            },
            injectImmediately: true,
        },            
        {
            injectImmediately: true,
            func() {
                let addTouchTools = () => {
                    self.removeEventListener('touchstart', addTouchTools, true);
                    console.debug('addTouchTools');
                    editorUtil.addActions({
                        "user.undo": {
                            label: "Undo",
                            precondition: "textInputFocus && !editorReadonly",
                            contextMenuGroupId: " 1_modification",
                            contextMenuOrder: 11,
                            run(editor) {
                                editor.trigger("", "undo");
                            },
                        },
                        "user.redo": {
                            label: "Redo",
                            precondition: "textInputFocus && !editorReadonly",
                            contextMenuGroupId: " 1_modification",
                            contextMenuOrder: 12,
                            run(editor) {
                                editor.trigger("", "redo");
                            },
                        },
                        "user.paste": {
                            label: "Paste Clipboard Text",
                            precondition: "textInputFocus && !editorReadonly",
                            contextMenuGroupId: "9_cutcopypaste",
                            contextMenuOrder: 4,
                            async run(editor) {
                                // Requires ACCESS_LEVEL >=30
                                if (self.browser) {
                                    try {
                                        await browser.permissions.request({ permissions: ['clipboardRead'] });
                                    } catch (e) {
                                        console.warn(e);
                                    }
                                }
                                try {
                                    let text = await navigator.clipboard.readText();
                                    if (!text) return;
                                    editor.executeEdits("", [{
                                        forceMoveMarkers: true,
                                        range: editor.getSelection(),
                                        text,
                                    }]);
                                } catch (e) {
                                    console.warn(e);
                                } finally {
                                    // await browser.permissions.remove({ permissions: ['clipboardRead'] });
                                }
                            },
                        },
                        "user.delete": {
                            label: "Delete",
                            precondition: "!editorReadonly && editorHasSelection",
                            contextMenuGroupId: "9_cutcopypaste",
                            contextMenuOrder: 5,
                            run(editor) {
                                editor.executeEdits("", [{
                                    forceMoveMarkers: true,
                                    range: editor.getSelection(),
                                    text: "",
                                }]);
                            },
                        },
                        "user.selectAll": {
                            label: "Select All",
                            precondition: "textInputFocus",
                            contextMenuGroupId: "9_cutcopypaste",
                            contextMenuOrder: 6,
                            run(editor) {
                                editor.setSelection(editor.getModel().getFullModelRange());
                            },
                        },
                        "user.find": {
                            label: "Find...",
                            precondition: "textInputFocus && !findWidgetVisible",
                            contextMenuGroupId: "view",
                            contextMenuOrder: 4.9,
                            run() {
                                editor.trigger("", "actions.find");
                            },
                        },
                    });
                };
                self.addEventListener('touchstart', addTouchTools, true);
            },
        },
    ],
})

Ну и при редактировании длинной статьи в наших виках, делайте так:

  • время от времени нажимайте на кнопку «Save» в окне Code-Editor — это еще будет не сохранение статьи, а сохранение в textarea вкладки с открытой на редактирование статьей.
  • а вот в этой вкладке, нажмите на нашу доработку — кнопку «Опубликовать» — т.е. без выхода из режима редактирования выобновите статью
  • и ее можно превьювить в какой-нибудь другой открытой вкладке — и все это без выхода из режима редактирования без потери контекста где вы находитесь и т.п.
  • если эти вкладки в FF запинить первыми, там можно переключаться между ними с помощью хоткеев «ALT-1», … «ALT-9».