diff --git a/TeXmacs/progs/kernel/texmacs/tm-dialogue.scm b/TeXmacs/progs/kernel/texmacs/tm-dialogue.scm index 8c77aeef43..208917efd4 100644 --- a/TeXmacs/progs/kernel/texmacs/tm-dialogue.scm +++ b/TeXmacs/progs/kernel/texmacs/tm-dialogue.scm @@ -13,7 +13,7 @@ (texmacs-module (kernel texmacs tm-dialogue) (:use (kernel texmacs tm-define))) -(import (liii json) +(import (liii njson) (liii time) (liii list)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -167,87 +167,67 @@ (define interactive-arg-version 1) (define interactive-arg-file "$TEXMACS_HOME_PATH/system/interactive.json") (define interactive-arg-recent-file-path "$TEXMACS_HOME_PATH/system/recent-files.json") - -(define (make-empty-interactive-arg-json) - `(("meta" . (("version" . ,interactive-arg-version))) - ("commands" . (())))) +(define interactive-arg-file-system + (url->system (string->url interactive-arg-file))) +(define interactive-arg-recent-file-system + (url->system (string->url interactive-arg-recent-file-path))) + +(define (make-empty-state kind) + (case kind + ((interactive-arg) + (let ((root (string->njson "{\"meta\":{},\"commands\":{}}"))) + (njson-set! root "meta" "version" interactive-arg-version) + root)) + ((recent-file) + (string->njson "{\"meta\":{\"version\":1,\"total\":0},\"files\":[]}")) + (else + (string->njson "{}")))) (define interactive-arg-json - (make-empty-interactive-arg-json)) + (make-empty-state 'interactive-arg)) (define interactive-arg-recent-file-json - `(("meta" . (("version" . 1) - ("total" . 0))) - ("files" . #()))) + (make-empty-state 'recent-file)) + +(define interactive-args-schema-v1 + (string->njson + "{\"type\":\"object\",\"required\":[\"meta\",\"commands\"],\"properties\":{\"meta\":{\"type\":\"object\",\"required\":[\"version\"],\"properties\":{\"version\":{\"type\":\"integer\",\"minimum\":1}}},\"commands\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"additionalProperties\":{\"type\":\"string\"}}}}}}")) + +(define recent-files-schema-v1 + (string->njson + "{\"type\":\"object\",\"required\":[\"meta\",\"files\"],\"properties\":{\"meta\":{\"type\":\"object\",\"required\":[\"version\",\"total\"],\"properties\":{\"version\":{\"type\":\"number\"},\"total\":{\"type\":\"integer\",\"minimum\":0}}},\"files\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"required\":[\"path\",\"name\",\"last_open\",\"open_count\",\"show\"],\"properties\":{\"path\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"last_open\":{\"type\":\"number\"},\"open_count\":{\"type\":\"number\"},\"show\":{\"type\":\"boolean\"}}}}}}")) -(define (interactive-arg-item-valid? item) - (and (json-object? item) - (let ((keys (json-keys item))) - (and (every string? keys) - (every (lambda (k) (string? (json-ref item k))) keys))))) +(define (njson-schema-valid? schema instance) + (catch #t + (lambda () + (let ((report (njson-schema-report schema instance))) + (hash-table-ref report 'valid?))) + (lambda args #f))) (define (interactive-args-json-valid? interactive-args) - (and (json-object? interactive-args) - (let* ((meta (json-ref interactive-args "meta")) - (commands (json-ref interactive-args "commands")) - (version (and (json-object? meta) (json-ref meta "version")))) - (and (json-object? meta) - (integer? version) - (>= version 1) - (json-object? commands) - (every string? (json-keys commands)) - (every (lambda (cmd) - (let ((items (json-ref commands cmd))) - (and (vector? items) - (every interactive-arg-item-valid? - (vector->list items))))) - (json-keys commands)))))) + (njson-schema-valid? interactive-args-schema-v1 interactive-args)) (define (interactive-command-learned command-name) - (let* ((commands (json-ref interactive-arg-json "commands")) - (items (and (json-object? commands) - (json-ref commands command-name)))) - (if (vector? items) (vector->list items) '()))) + (let-njson ((commands (njson-ref interactive-arg-json "commands"))) + (if (njson-contains-key? commands command-name) + (let-njson ((items (njson-ref commands command-name))) + (if (njson-array? items) + (vector->list (njson->json items)) + '())) + '()))) (define (set-interactive-command-learned command-name items) - (let* ((commands (json-ref interactive-arg-json "commands")) - (commands (if (json-object? commands) commands '(()))) - (payload (list->vector items)) - (commands* (if (json-contains-key? commands command-name) - (json-set commands command-name payload) - (json-push commands command-name payload)))) - (set! interactive-arg-json - (json-set interactive-arg-json "commands" commands*)))) + (let-njson ((payload (json->njson (list->vector items)))) + (njson-set! interactive-arg-json "commands" command-name payload))) (define (remove-interactive-command-learned command-name) - (let* ((commands (json-ref interactive-arg-json "commands")) - (commands (if (json-object? commands) commands '(()))) - (commands* (if (json-contains-key? commands command-name) - (json-drop commands command-name) - commands))) - (set! interactive-arg-json - (json-set interactive-arg-json "commands" commands*)))) - -(define (recent-file-item-valid? item) - (and (json-object? item) - (string? (json-ref item "path")) - (string? (json-ref item "name")) - (number? (json-ref item "last_open")) - (number? (json-ref item "open_count")) - (boolean? (json-ref item "show")))) + (let-njson ((commands (njson-ref interactive-arg-json "commands"))) + (when (njson-contains-key? commands command-name) + (njson-drop! interactive-arg-json "commands" command-name)))) (define (recent-files-json-valid? recent-files) - (and (json-object? recent-files) - (let* ((meta (json-ref recent-files "meta")) - (files (json-ref recent-files "files")) - (version (and (json-object? meta) (json-ref meta "version"))) - (total (and (json-object? meta) (json-ref meta "total")))) - (and (json-object? meta) - (number? version) - (integer? total) (>= total 0) - (vector? files) - (every recent-file-item-valid? (vector->list files)))))) + (njson-schema-valid? recent-files-schema-v1 recent-files)) #| @@ -273,98 +253,82 @@ unspecified 逻辑 ---- 1. 调用 `recent-files-index-by-path` 查找 `path` 在 `files` 中的索引。 -2. 若找到索引,调用 `json-drop` 删除该项。 +2. 若找到索引,调用 `njson-drop!` 删除该项。 3. 将 `meta.total` 减一(不低于 0)。 4. 将更新后的 JSON 结构回写到 `interactive-arg-recent-file-json`。 |# (define-public (recent-files-remove-by-path path) (let ((idx (recent-files-index-by-path interactive-arg-recent-file-json path))) (when idx - (let* ((total (json-ref interactive-arg-recent-file-json "meta" "total")) + (let* ((total (njson-ref interactive-arg-recent-file-json "meta" "total")) (total (if (number? total) total 0)) - (new-total (if (<= total 0) 0 (- total 1))) - (r1 (json-drop interactive-arg-recent-file-json "files" idx))) - (set! interactive-arg-recent-file-json - (json-set r1 "meta" "total" new-total)))))) + (new-total (if (<= total 0) 0 (- total 1)))) + (njson-drop! interactive-arg-recent-file-json "files" idx) + (njson-set! interactive-arg-recent-file-json "meta" "total" new-total))))) (define (recent-files-apply-lru recent-files limit) - (let* ((files (json-ref recent-files "files")) - (n (vector-length files)) - (indexed - (let loop ((i 0) (acc '())) - (if (>= i n) acc - (let* ((item (vector-ref files i)) - (t (json-ref item "last_open")) - (t (if (number? t) t 0))) - (loop (+ i 1) (cons (cons i t) acc)))))) - (sorted (sort indexed (lambda (a b) (> (cdr a) (cdr b)))))) - (if (<= n limit) - (json-set recent-files "files" - (list->vector - (map (lambda (p) (vector-ref files (car p))) sorted))) - (let* ((keep (take sorted limit)) - (drop (drop sorted limit)) - (new-files - (list->vector - (append - (map (lambda (p) - (let* ((item (vector-ref files (car p)))) - (json-set item "show" #t))) - keep) - (map (lambda (p) - (let* ((item (vector-ref files (car p)))) - (json-set item "show" #f))) - drop))))) - (json-set recent-files "files" new-files))))) + (let-njson ((files (njson-ref recent-files "files"))) + (let* ((n (njson-size files)) + (indexed + (let loop ((i 0) (acc '())) + (if (>= i n) acc + (let* ((t (njson-ref files i "last_open")) + (t (if (number? t) t 0))) + (loop (+ i 1) (cons (cons i t) acc)))))) + (sorted (sort indexed (lambda (a b) (> (cdr a) (cdr b)))))) + (let-njson ((new-files (string->njson "[]"))) + (let loop ((rank 0) (rest sorted)) + (when (pair? rest) + (let* ((p (car rest)) + (idx (car p)) + (show? (< rank limit))) + (let-njson ((item (njson-ref files idx))) + (njson-set! item "show" show?) + (njson-append! new-files item)) + (loop (+ rank 1) (cdr rest))))) + (njson-set! recent-files "files" new-files))) + recent-files)) (define (recent-files-add recent-files path name) - (let* ((files (json-ref recent-files "files")) - (idx (vector-length files)) - (item `(("path" . ,path) - ("name" . ,name) - ("last_open" . ,(current-second)) - ("open_count" . 1) - ("show" . #t))) - (total (json-ref recent-files "meta" "total")) - (total (if (number? total) total 0)) - (r1 (json-set - (json-push recent-files "files" idx item) - "meta" "total" (+ total 1)))) - (recent-files-apply-lru r1 25))) + (let-njson ((item (json->njson + `(("path" . ,path) + ("name" . ,name) + ("last_open" . ,(current-second)) + ("open_count" . 1) + ("show" . #t))))) + (njson-append! recent-files "files" item)) + (let* ((total (njson-ref recent-files "meta" "total")) + (total (if (number? total) total 0))) + (njson-set! recent-files "meta" "total" (+ total 1))) + (recent-files-apply-lru recent-files 25)) (define (recent-files-set recent-files idx) - (let* ((item (json-ref recent-files "files" idx)) - (path* (json-ref item "path")) - (name* (json-ref item "name")) - (count* (json-ref item "open_count")) - (count* (if (number? count*) count* 0)) - (new-item `(("path" . ,path*) - ("name" . ,name*) - ("last_open" . ,(current-second)) - ("open_count" . ,(+ count* 1)) - ("show" . #t))) - (r1 (json-set recent-files "files" idx new-item))) - (recent-files-apply-lru r1 25))) + (let* ((count* (njson-ref recent-files "files" idx "open_count")) + (count* (if (number? count*) count* 0))) + (njson-set! recent-files "files" idx "last_open" (current-second)) + (njson-set! recent-files "files" idx "open_count" (+ count* 1)) + (njson-set! recent-files "files" idx "show" #t) + (recent-files-apply-lru recent-files 25))) (define (recent-files-index-by-path recent-files path) - (let ((files (json-ref recent-files "files"))) + (let-njson ((files (njson-ref recent-files "files"))) (let loop ((i 0)) - (if (>= i (vector-length files)) + (if (>= i (njson-size files)) #f - (let ((item (vector-ref files i))) - (if (equal? (json-ref item "path") path) - i - (loop (+ i 1)))))))) + (if (equal? (njson-ref files i "path") path) + i + (loop (+ i 1))))))) (define (recent-files-paths recent-files) - (let ((files (json-ref recent-files "files"))) - (map (lambda (item) - (list (cons "0" (json-ref item "path")))) - (vector->list files)))) + (let-njson ((files (njson-ref recent-files "files"))) + (let loop ((i 0) (n (njson-size files)) (acc '())) + (if (>= i n) (reverse acc) + (loop (+ i 1) n + (cons (list (cons "0" (njson-ref files i "path"))) acc)))))) (define (list-but l1 l2) @@ -508,10 +472,9 @@ unspecified (when (symbol? fun) (case fun ((recent-buffer) + (njson-free interactive-arg-recent-file-json) (set! interactive-arg-recent-file-json - `(("meta" . (("version" . 1) - ("total" . 0))) - ("files" . #())))) + (make-empty-state 'recent-file))) (else (with name (procedure-string-name fun) (when (string? name) @@ -628,45 +591,36 @@ unspecified ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (save-learned) - (string-save - (json->string interactive-arg-json) - (string->url interactive-arg-file)) - (string-save - (json->string interactive-arg-recent-file-json) - (string->url interactive-arg-recent-file-path))) + (njson->file interactive-arg-file-system interactive-arg-json) + (njson->file interactive-arg-recent-file-system interactive-arg-recent-file-json)) + +(define (load-njson-with-fallback file valid? fallback-maker) + (catch #t + (lambda () + (let ((parsed (file->njson file))) + (if (valid? parsed) + parsed + (begin + (njson-free parsed) + (fallback-maker))))) + (lambda args + (fallback-maker)))) + +(define (reload-state current-state file valid? fallback-maker) + (njson-free current-state) + (load-njson-with-fallback file valid? fallback-maker)) (define (retrieve-learned) - (set! interactive-arg-json (make-empty-interactive-arg-json)) - (when (url-exists? interactive-arg-file) - (set! interactive-arg-json - (catch #t - (lambda () - (let ((interactive-args - (string->json - (string-load - (string->url interactive-arg-file))))) - (if (interactive-args-json-valid? interactive-args) - interactive-args - (make-empty-interactive-arg-json)))) - (lambda args - (make-empty-interactive-arg-json))))) - (when (url-exists? interactive-arg-recent-file-path) - (set! interactive-arg-recent-file-json - (catch #t - (lambda () - (let ((recent-files - (string->json - (string-load - (string->url interactive-arg-recent-file-path))))) - (if (recent-files-json-valid? recent-files) - recent-files - `(("meta" . (("version" . 1) - ("total" . 0))) - ("files" . #()))))) - (lambda args - `(("meta" . (("version" . 1) - ("total" . 0))) - ("files" . #()))))))) + (set! interactive-arg-json + (reload-state interactive-arg-json + interactive-arg-file-system + interactive-args-json-valid? + (lambda () (make-empty-state 'interactive-arg)))) + (set! interactive-arg-recent-file-json + (reload-state interactive-arg-recent-file-json + interactive-arg-recent-file-system + recent-files-json-valid? + (lambda () (make-empty-state 'recent-file))))) (on-entry (retrieve-learned)) diff --git a/TeXmacs/progs/source/shortcut-edit.scm b/TeXmacs/progs/source/shortcut-edit.scm index 4552b0059c..049109e170 100644 --- a/TeXmacs/progs/source/shortcut-edit.scm +++ b/TeXmacs/progs/source/shortcut-edit.scm @@ -13,13 +13,15 @@ (texmacs-module (source shortcut-edit) (:use (source macro-edit))) -(import (liii json)) +(import (liii njson)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Management of the list of user keyboard shortcuts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define user-shortcuts-file "$TEXMACS_HOME_PATH/system/shortcuts.json") +(define user-shortcuts-file-system + (url->system (string->url user-shortcuts-file))) (define user-shortcuts-version 1) (define (make-shortcut-entry sh cmd) @@ -27,63 +29,62 @@ ("command" . ,cmd))) (define (shortcut-entry-shortcut entry) - (json-ref entry "shortcut")) + (assoc-ref entry "shortcut")) (define (shortcut-entry-command entry) - (json-ref entry "command")) + (assoc-ref entry "command")) (define (shortcut-entry-valid? entry) - (and (json-object? entry) + (and (pair? entry) (string? (shortcut-entry-shortcut entry)) (string? (shortcut-entry-command entry)))) -(define (shortcut-entries-valid? entries) - (or (null? entries) - (and (shortcut-entry-valid? (car entries)) - (shortcut-entries-valid? (cdr entries))))) - -(define (user-shortcuts-json-valid? json) - (and (json-object? json) - (let* ((meta (json-ref json "meta")) - (shortcuts (json-ref json "shortcuts")) - (version (and (json-object? meta) (json-ref meta "version"))) - (total (and (json-object? meta) (json-ref meta "total")))) - (and (json-object? meta) - (integer? version) - (integer? total) - (>= total 0) - (vector? shortcuts) - (== total (vector-length shortcuts)) - (shortcut-entries-valid? (vector->list shortcuts)))))) - -(define (make-user-shortcuts-json shortcuts) - `(("meta" . (("version" . ,user-shortcuts-version) - ("total" . ,(vector-length shortcuts)))) - ("shortcuts" . ,shortcuts))) +(define user-shortcuts-schema-v1 + (string->njson + "{\"type\":\"object\",\"required\":[\"meta\",\"shortcuts\"],\"properties\":{\"meta\":{\"type\":\"object\",\"required\":[\"version\",\"total\"],\"properties\":{\"version\":{\"type\":\"integer\"},\"total\":{\"type\":\"integer\",\"minimum\":0}}},\"shortcuts\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"required\":[\"shortcut\",\"command\"],\"properties\":{\"shortcut\":{\"type\":\"string\"},\"command\":{\"type\":\"string\"}}}}}}")) + +(define (njson-schema-valid? schema instance) + (catch #t + (lambda () + (let ((report (njson-schema-report schema instance))) + (hash-table-ref report 'valid?))) + (lambda args #f))) + +(define (user-shortcuts-json-valid? data) + (and (njson-schema-valid? user-shortcuts-schema-v1 data) + (let-njson ((shortcuts (njson-ref data "shortcuts")) + (total (njson-ref data "meta" "total"))) + (and (integer? total) + (== total (njson-size shortcuts)))))) + +(define (make-user-shortcuts-json entries) + (json->njson + `(("meta" . (("version" . ,user-shortcuts-version) + ("total" . ,(length entries)))) + ("shortcuts" . ,(list->vector entries))))) (define (make-empty-user-shortcuts-json) - (make-user-shortcuts-json #())) + (make-user-shortcuts-json '())) (define current-user-shortcuts (make-empty-user-shortcuts-json)) +(define (replace-current-user-shortcuts! next) + (njson-free current-user-shortcuts) + (set! current-user-shortcuts next)) + (define (current-user-shortcuts-vector) - (with shortcuts (json-ref current-user-shortcuts "shortcuts") - (if (vector? shortcuts) shortcuts #()))) + (catch #t + (lambda () + (let-njson ((shortcuts (njson-ref current-user-shortcuts "shortcuts"))) + (if (njson-array? shortcuts) (njson->json shortcuts) #()))) + (lambda args #()))) (define (current-user-shortcuts-list) (vector->list (current-user-shortcuts-vector))) -(define (normalize-user-shortcuts-json json) - (let* ((shortcuts (if (and (json-object? json) (vector? (json-ref json "shortcuts"))) - (json-ref json "shortcuts") - #())) - (entries (vector->list shortcuts)) - (valid (list-filter entries shortcut-entry-valid?))) - (make-user-shortcuts-json (list->vector valid)))) - (define (set-current-user-shortcuts-list entries) - (set! current-user-shortcuts - (make-user-shortcuts-json (list->vector entries)))) + (replace-current-user-shortcuts! + (make-user-shortcuts-json entries))) (define (find-user-shortcut-entry sh) (let loop ((entries (current-user-shortcuts-list))) @@ -101,28 +102,30 @@ (eval `(kbd-unmap ,sh))) (define (reset-user-shortcuts) - (set! current-user-shortcuts (make-empty-user-shortcuts-json)) + (replace-current-user-shortcuts! (make-empty-user-shortcuts-json)) (save-user-shortcuts)) (define (load-user-shortcuts) - (set! current-user-shortcuts (make-empty-user-shortcuts-json)) + (replace-current-user-shortcuts! (make-empty-user-shortcuts-json)) (when (url-exists? user-shortcuts-file) (let ((loaded (catch #t (lambda () - (string->json (string-load user-shortcuts-file))) + (file->njson user-shortcuts-file-system)) (lambda args #f)))) (if (user-shortcuts-json-valid? loaded) - (set! current-user-shortcuts - (normalize-user-shortcuts-json loaded)) - (reset-user-shortcuts)))) + (replace-current-user-shortcuts! loaded) + (begin + (catch #t + (lambda () (njson-free loaded)) + (lambda args #f)) + (reset-user-shortcuts))))) (for (entry (current-user-shortcuts-list)) (apply-user-shortcut (shortcut-entry-shortcut entry) (shortcut-entry-command entry)))) (define (save-user-shortcuts) - (string-save (json->string current-user-shortcuts) - user-shortcuts-file)) + (njson->file user-shortcuts-file-system current-user-shortcuts)) (tm-define (init-user-shortcuts) (load-user-shortcuts)) diff --git a/devel/201_89.md b/devel/201_89.md new file mode 100644 index 0000000000..e4699a58a8 --- /dev/null +++ b/devel/201_89.md @@ -0,0 +1,56 @@ +# [201_89] + +### 如何测试 + +##### interactive +1. 点击`工具->调试工具`,随后点击`调试->运行->执行scheme表达式`,在输入框中输入`(display* "123\n")`。 +2. 再次点击`调试->运行->执行scheme表达式`,里面的内容还在。 +3. 点击`插入->表格->小表格`,随后点击焦点工具栏上的![alt text](201_82.png) ,选择`宽度->固定`,输入50. +4. 关掉再次打开,里面的内容还是50. +5. 关闭程序,执行 +``` +cat ~/.local/share/moganlab/system/interactive.json | python3 -m json.tool +``` +会输出最终存储的json +6. 编辑`~/.local/share/moganlab/system/interactive.json`,随便修改一个字段名 +7. 重新打开程序,之前输入的东西会消失 + + +##### recent-files +1. 点击`文件->打开`,打开几个文件。 +2. 点击`文件->最近使用`,能看到刚刚打开的几个文件。关闭程序,执行`cat ~/.local/share/moganlab/system/recent-files.json | python3 -m json.tool`,能观察到最近打开的文件。 +3. 再次打开程序,点击`文件->最近使用`,能看到刚刚打开的几个文件。 +4. 关闭一个文件a,再点击`文件->最近使用`打开文件a,观察能否打开成功,随后点击`文件->最近使用`,文件a的选项在第一处。 +5. 点击`文件->最近使用`,选择一个已经打开的文件,会跳转过去,随后点击`文件->最近使用`,选择的文件位于第一处。 +5. 删除一个文件,再尝试通过`文件->最近使用`打开它,会弹出窗口提示文件不存在,随后点击`文件->最近使用`,观察该文件是否存在。 +6. 关闭程序,执行`cat ~/.local/share/moganlab/system/recent-files.json | python3 -m json.tool`,观察字段是否准确。 +7. 关闭程序,编辑`~/.local/share/moganlab/system/recent-files.json`,输入如下内容 +``` +{meta:{total:4},files:[{path:"\/home\/da\/git\/mogan\/TeXmacs\/doc\/manual\/manu.gettingstarted.zh.tmu",name:"manu.gettingstarted.zh.tmu",last_open:1770625505.296669,open_count:1,show:true},{path:"\/home\/da\/git\/mogan\/TeXmacs\/doc\/about\/mogan\/stem.zh.tmu",name:"stem.zh.tmu",last_open:1770625495.617651,open_count:2,show:true},{path:"\/home\/da\/DevTeam\/程设小作业资料.tmu",name:"程设小作业资料.tmu",last_open:1770618896.320695,open_count:2,show:true},{path:"\/home\/da\/DevTeam\/home\/da\/快捷键顺序调整.tmu",name:"快捷键顺序调整.tmu",last_open:1770618870.53241,open_count:1,show:true}]} +``` +打开程序,点击`文件->最近使用`,由于json结构不匹配,此时是空列表。 +8. 关闭程序,编辑`~/.local/share/moganlab/system/recent-files.json`,测试在非法json时能否正常运行 +``` +{meta:{total:4},files:[{path:"\/home\/da\/git\/mogan\/TeXmacs\/doc\/manual\/manu.gettingstarted.zh.tmu",name:"manu.gettingstarted.zh.tmu",last_open:1770625505.296669,open_count:1,show:true},{path:"\/home\/da\/git\/mogan\/TeXmacs\/doc\/about\/mogan\/stem.zh.tmu",name:"stem.zh.tmu",last_open:1770625495.617651,open_count:2,show:true},{path:"\/home\/da\/DevTeam\/程设小作业资料.tmu",name:"程设小作业资料.tmu",last_open:1770618896.320695,open_count:2,show:true},{path:"\/home\/da\/DevTeam\/home\/da\/快捷键顺序调整.tmu",name:"快捷键顺序调整.tmu",last_open:1770618870.53241,open_cou +``` +打开程序,点击`文件->最近使用`,由于非法json,此时是空列表。 + +##### 自定义快捷键 +1. 点击`工具->键盘->编辑键盘快捷键`. +2. 快捷键设置`< < 1` ,命令为`“test”` +3. 保存后在文档中输入`<<1`,字符串test被自动输入进去 +4. 重新打开软件,再打开快捷键编辑器,之前设置的快捷键还在 +5. 删除快捷键,重新打开软件,对应的快捷键被清除 +6. 快捷键设置`< < 1` ,命令为`“test”` +7. 关掉软件,编辑`~/.local/share/moganlab/system/shortcuts.json` +``` +{"meta":{"version":1,"total":0},"shortcuts":[]} +``` +打开程序,点击`工具->键盘->编辑键盘快捷键`.,由于json结构不准确,快捷键设置被清空 +8. 快捷键设置`< < 1` ,命令为`“test”`,关掉软件,编辑`~/.local/share/moganlab/system/shortcuts.json` +``` +{"meta":{"version":1,"total":0},"shortcuts": +``` +打开程序,点击`工具->键盘->编辑键盘快捷键`.,由于json结构非法,快捷键设置被清空 + +## 2026/03/04 将目前json的使用从(liii json)迁移到(liii njson)