textadept-context-files.lua /size: 23 Kb    last modification: 2020-07-01 14:35
1local info = {
2    version   = 1.002,
3    comment   = "file handler for textadept for context/metafun",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files",
7}
8
9local lexer   = require("scite-context-lexer")
10local context = lexer.context
11
12local char, format, gsub = string.char, string.format, string.gsub
13
14-- What is _CHARSET doing ... I don't want any messing with conversion at all. Scite is
15-- more clever with e.g. pdf. How can I show non ascii as escapes.
16
17-- I'll add a few more keybindings. I mostly made this file for my own use and as a
18-- fallback for SciTE as it runs on all os's. It might evolve ... who knows.
19
20io.encodings = {
21    "UTF-8",
22    "ASCII",
23    "UTF-16",
24}
25
26-- We need this for for instance pdf files (faster too):
27
28local sevenbitascii   = { }
29for i=127,255 do
30    sevenbitascii[char(i)] = format("0x%02X",i)
31end
32
33local function setsevenbitascii(buffer)
34    -- we cannot directly assign sevenbitascii to buffer
35    local representation = buffer.representation
36    for k, v in next, sevenbitascii do
37        representation[k] = v
38    end
39end
40
41-- Here we rebind keys. For this we need to load the alternative runner framework. I will
42-- probably change the menu.
43
44local oldrunner = textadept.run
45local runner    = require("textadept-context-runner")
46
47-- local function userunner(runner)
48--     --
49--     keys [OSX and 'mr' or                  'cr'  ] = runner.process or runner.run
50--     keys [OSX and 'mR' or (GUI and 'cR' or 'cmr')] = runner.check   or runner.compile
51--     keys [OSX and 'mB' or (GUI and 'cB' or 'cmb')] = runner.preview or runner.build
52--     keys [OSX and 'mX' or (GUI and 'cX' or 'cmx')] = runner.quit    or runner.stop
53--     --
54--     textadept.menu.menubar [_L['_Tools']] [_L['_Run']]     [2] = runner.process or runner.run
55--     textadept.menu.menubar [_L['_Tools']] [_L['_Compile']] [2] = runner.check   or runner.compile
56--     textadept.menu.menubar [_L['_Tools']] [_L['Buil_d']]   [2] = runner.preview or runner.build
57--     textadept.menu.menubar [_L['_Tools']] [_L['S_top']]    [2] = runner.quit    or runner.stop
58--     --
59-- end
60
61-- I played a while with supporting both systems alongsize but getting the menus
62-- synchronized is a real pain and semi-random. So, I decided to just drop the
63-- old. And I don't want to implement a full variant now. Anyway, after that
64-- conclusion I decided to replace not only the tools menu.
65
66local SEPARATOR = { "" }
67local newmenu   = { }
68local newkeys   = { }
69
70do
71
72    newmenu.file = {
73
74        title = "_File",
75
76        { "_New",          buffer.new },
77        { "_Open",         io.open_file },
78        { "Open _Recent",  io.open_recent_file },
79        { "Re_load",       io.reload_file },
80        { "_Save",         io.save_file },
81        { "Save _As",      io.save_file_as },
82        { "Save All",      io.save_all_files },
83
84        SEPARATOR,
85
86        { "_Close",        io.close_buffer },
87        { "Close All",     io.close_all_buffers },
88
89     -- SEPARATOR,
90
91     -- { "Loa_d Session", textadept.session.load },
92     -- { "Sav_e Session", textadept.session.save },
93
94        SEPARATOR,
95
96        { _L["_Quit"],     quit },
97
98    }
99
100    -- maybe just the same keys on all ... or duplicate on osx
101
102    newkeys[OSX and "mn"  or "cn"]  = buffer.new
103    newkeys[OSX and "mo"  or "co"]  = io.open_file
104    newkeys[OSX and "cmo" or "cao"] = io.open_recent_file
105    newkeys[OSX and "ms"  or "cs"]  = io.save_file
106    newkeys[OSX and "mS"  or "cS"]  = io.save_file_as
107    newkeys[OSX and "mw"  or "cw"]  = io.close_buffer
108    newkeys[OSX and "mW"  or "cW"]  = io.close_all_buffers
109
110end
111
112do
113
114    local function complete_symbol()
115        textadept.editing.autocomplete(buffer:get_lexer(true))
116    end
117
118    newmenu.edit = {
119
120        title = "_Edit",
121
122        SEPARATOR,
123
124        { "_Undo",                 buffer.undo },
125        { "_Redo",                 buffer.redo },
126
127        SEPARATOR,
128
129        { "Cu_t",                  buffer.cut },
130        { "_Copy",                 buffer.copy },
131        { "_Paste",                buffer.paste },
132        { "_Delete",               buffer.clear },
133        { "Select _All",           buffer.select_all },
134
135        SEPARATOR,
136
137        { "Duplicate _Line",       buffer.line_duplicate },
138
139        SEPARATOR,
140
141        { "Toggle _Block Comment", runner.blockcomment },
142        { "_Upper Case Selection", buffer.upper_case },
143        { "_Lower Case Selection", buffer.lower_case },
144
145    }
146
147    newkeys[OSX and "mz" or "cz"]  = buffer.undo
148    newkeys[OSX and "my" or "cy"]  = buffer.redo
149    newkeys[OSX and "mx" or "cx"]  = buffer.cut
150    newkeys[OSX and "mc" or "cc"]  = buffer.copy
151    newkeys[OSX and "mv" or "cv"]  = buffer.paste
152    newkeys[OSX and "ma" or "ca"]  = buffer.select_all
153
154    newkeys[OSX and "mD" or "cD"]  = textadept.editing.select_word
155    newkeys[OSX and "mN" or "cN"]  = textadept.editing.select_line
156    newkeys[OSX and "mP" or "cP"]  = textadept.editing.select_paragraph
157
158    newkeys["del"]                 = buffer.clear
159    newkeys["cy"]                  = buffer.redo
160
161    newkeys[OSX and "md" or "cd"]  = buffer.line_duplicate
162    newkeys[OSX and "cu" or "cau"] = buffer.upper_case
163    newkeys[OSX and "cU" or "caU"] = buffer.lower_case
164
165    newkeys[OSX and "mq" or "cq"]  = runner.blockcomment
166
167    newkeys[OSX and "ml" or "cl"]  = buffer.line_delete
168
169    -- Do I ever use these?
170
171 -- newkeys["cf"]     = buffer.char_right
172 -- newkeys["cF"]     = buffer.char_right_extend
173 -- newkeys["cmf"]    = buffer.word_right
174 -- newkeys["cmF"]    = buffer.word_right_extend
175 -- newkeys["cb"]     = buffer.char_left
176 -- newkeys["cB"]     = buffer.char_left_extend
177 -- newkeys["cmb"]    = buffer.word_left
178 -- newkeys["cmB"]    = buffer.word_left_extend
179 -- newkeys["cn"]     = buffer.line_down
180 -- newkeys["cN"]     = buffer.line_down_extend
181 -- newkeys["cp"]     = buffer.line_up
182 -- newkeys["cP"]     = buffer.line_up_extend
183 -- newkeys["ca"]     = buffer.vc_home
184 -- newkeys["cA"]     = buffer.vc_home_extend
185 -- newkeys["ce"]     = buffer.line_end
186 -- newkeys["cE"]     = buffer.line_end_extend
187 -- newkeys["aright"] = buffer.word_right
188 -- newkeys["aleft"]  = buffer.word_left
189 -- newkeys["cdv"]    = buffer.clear
190 -- newkeys["ck"]     = function() buffer:line_end_extend() buffer:cut()  end
191 -- newkeys["cl"]     = buffer.vertical_centre_caret
192
193    newkeys.fn = OSX and function() return true end or nil
194
195    newkeys[OSX and "c@" or "c "] = complete_symbol
196
197end
198
199do
200
201    local function find_in_file()
202        ui.find.in_files = false
203        ui.find.focus()
204    end
205
206    local function find_in_files()
207        ui.find.in_files = true
208        ui.find.focus()
209    end
210
211    local function find_next_in_files()
212        ui.find.goto_file_found(false,true)
213    end
214
215    local function find_previous_in_files()
216        ui.find.goto_file_found(false,false)
217    end
218
219    newmenu.search = {
220
221        title = "_Search",
222
223        SEPARATOR,
224
225        { "_Find",                     find_in_file },
226        { "Find _Next",                ui.find.find_next },
227        { "Find _Previous",            ui.find.find_prev },
228        { "_Replace",                  ui.find.replace },
229        { "Replace _All",              ui.find.replace_all },
230        { "Find _Incremental",         ui.find.find_incremental },
231
232        SEPARATOR,
233
234        { "Find in Fi_les",            find_in_files },
235        { "Goto Nex_t File Found",     find_next_in_files },
236        { "Goto Previou_s File Found", find_previous_in_files },
237
238        SEPARATOR,
239
240        { "_Jump to",                  textadept.editing.goto_line }
241
242    }
243
244    -- The few times I use osx I want the same keys ... better explicitly handle
245    -- "not GUI" but I have to test the curses version first anyway.
246
247    newkeys[OSX and "mf" or "cf"]    = find_in_file
248    newkeys[OSX and "mg" or "cg"]    = ui.find.find_next
249    newkeys[OSX and "mG" or "cG"]    = ui.find.find_prev
250    newkeys[OSX and "mg" or "cg"]    = textadept.editing.goto_line
251
252    newkeys["f3"]                    = not OSX and ui.find.find_next or nil
253    newkeys["sf3"]                   = not OSX and ui.find.find_prev or nil
254
255    newkeys[OSX and "cr"  or "car"]  = ui.find.replace
256    newkeys[OSX and "cR"  or "caR"]  = ui.find.replace_all
257    newkeys[OSX and "cmf" or "caf"]  = ui.find.find_incremental
258
259    newkeys[OSX and "mF"  or "cF"]   = find_in_files
260    newkeys[OSX and "cmg" or "cag"]  = find_next_in_files
261    newkeys[OSX and "cmG" or "caG"]  = find_previous_in_files
262
263end
264
265do
266
267    io.quick_open_max = 5000
268
269    local function isdir(path)
270        return path and path ~= "" and lfs.attributes(path,"mode") == "directory"
271    end
272
273    local function resolveroot(path)
274        local path = runner.resultof("mtxrun --resolve-path TEXMFCONTEXT")
275        if path then
276            return string.match(path,"(.-)%s$")
277        end
278    end
279
280    local function opencurrentdirectory()
281        local path = buffer.filename
282        if path and path ~= "" then
283            path = string.match(path,"^(.+)[/\\]")
284            if isdir(path) then
285                io.quick_open(path)
286            end
287        end
288    end
289
290    local function openuserdirectory()
291        local path = resolveroot("TEXMFPROJECT")
292        if isdir(path) then
293            io.quick_open(path .. "/tex/context/user")
294        end
295    end
296
297    local function openbasedirectory()
298        local path = resolveroot("TEXMFCONTEXT")
299        if isdir(path) then
300            io.quick_open(path .. "/tex/context/base/mkiv")
301        end
302    end
303
304    local started = false
305
306    local function startservice()
307        if WIN32 then
308            os.execute([[cmd /c start /min "Context Documentation" mtxrun --script server --auto]])
309        else
310            os.execute([[mtxrun --script server --start > ~/context-wwwserver.log &]])
311        end
312        started = true
313    end
314
315    local function showcommand()
316     -- if not started then
317     --     startservice()
318     -- end
319        local start = buffer.selection_n_start[0]
320        local stop  = buffer.selection_n_end[0]
321        if start == stop then
322            buffer:set_target_range(buffer:word_start_position(start,true),buffer:word_end_position(stop,true))
323        else
324            buffer:set_target_range(start,stop)
325        end
326        local word = buffer.target_text
327        os.execute(format([[mtxrun --gethelp --url="http://localhost:8088/mtx-server-ctx-help.lua?command=%s"]],word or ""))
328    end
329
330    newmenu.tools = {
331
332        title = "_Tools",
333
334        SEPARATOR,
335
336        { "Check Source",            runner.check },
337        { "Process Source",          runner.process },
338        { "Preview Result",          runner.preview },
339        { "Show Log File",           runner.install("logfile") },
340        { "Quit",                    runner.quit },
341
342        SEPARATOR,
343
344        { "Open Current Directory",  opencurrentdirectory },
345        { "Open User Directory",     openuserdirectory },
346        { "Open Base Directory",     openbasedirectory },
347
348        SEPARATOR,
349
350        { "Purge Files",             runner.install("purge") },
351        { "Clear Cache",             runner.install("clear") },
352        { "Generate File Database",  runner.install("generate") },
353        { "Generate Font Database",  runner.install("fonts") },
354
355        SEPARATOR,
356
357        { "Typeset Listing",         runner.install("listing") },
358        { "Process and Arrange",     runner.install("arrange") },
359
360        SEPARATOR,
361
362        { "Start Document Service",  startservice },
363        { "Goto Document Service",   showcommand },
364
365        SEPARATOR,
366
367        { "Show Unicodes",           runner.unicodes },
368
369        -- We need this bogus entry because otherwise we get a message due to macros.lua. I 
370        -- might need to come up with some proper placeholder. Well, let's for now just 
371        -- live with the crash. 
372
373     -- SEPARATOR,
374     --
375     -- { "Select Co_mmand",         textadept.editing.goto_line },
376    
377}
378
379 -- newkeys[OSX and "mc" or "cc"] = runner.check
380    newkeys[OSX and "mr" or "cr"] = runner.process
381    newkeys[OSX and "mp" or "cp"] = runner.preview
382 -- newkeys[OSX and "mx" or "cx"] = runner.quit -- makes no sense
383
384    newkeys["f7"]  = runner.process
385    newkeys["f12"] = runner.process
386
387    newkeys["f2"]  = runner.unicodes
388
389end
390
391do
392
393    local function use_tabs()
394        buffer.use_tabs = not buffer.use_tabs
395        events.emit(events.UPDATE_UI) -- for updating statusbar
396    end
397
398    local function set_eol_mode_crlf()
399        set_eol_mode(buffer.EOL_CRLF)
400    end
401
402    local function set_eol_mode_lf()
403        set_eol_mode(buffer.EOL_LF)
404    end
405
406    local function show_eol()
407        buffer.view_eol = not buffer.view_eol
408    end
409
410    local function wrap_mode()
411        buffer.wrap_mode = buffer.wrap_mode == 0 and buffer.WRAP_WHITESPACE or 0
412    end
413
414    function show_white_space()
415        buffer.view_ws = buffer.view_ws == 0 and buffer.WS_VISIBLEALWAYS or 0
416    end
417
418    local function update_lexing()
419        buffer:colourise(0,-1)
420    end
421
422    function set_endoding_utf8()
423        set_encoding("UTF-8")
424    end
425
426    function set_encoding_ascii()
427        set_encoding("ASCII")
428    end
429
430    function set_endoding_utf16le()
431        set_encoding("UTF-16LE")
432    end
433
434    function set_endoding_utf16Be()
435        set_encoding("UTF-16BE")
436    end
437
438    function goto_prev_buffer()
439        view:goto_buffer(-1)
440    end
441
442    function goto_next_buffer()
443        view:goto_buffer(1)
444    end
445
446    newmenu.buffer = {
447
448        title = "_Buffer",
449
450        SEPARATOR,
451
452        { "_Previous Buffer",  goto_prev_buffer },
453        { "_Next Buffer",      goto_next_buffer },
454        { "_Switch to Buffer", ui.switch_buffer },
455
456        SEPARATOR,
457
458        { "_Toggle Use Tabs", use_tabs },
459        {
460            title = "EOL Mode",
461
462            { "_CRLF", set_eol_mode_crlf },
463            { "_LF",   set_eol_mode_lf },
464        },
465        {
466            title = "Encoding",
467
468            { "_ASCII",     set_encoding_ascii },
469            { "_UTF-8",     set_encoding_utf8 },
470            { "UTF-16-_BE", set_encoding_utf16le },
471            { "UTF-16-_LE", set_encoding_utf16be },
472        },
473
474        SEPARATOR,
475
476        { "Toggle View _EOL",     show_eol },
477        { "Toggle _Wrap Mode",    wrap_mode  },
478        { "Toggle View _Spacing", show_whitespace },
479
480        SEPARATOR,
481
482        { "Select _Lexer",                textadept.file_types.select_lexer },
483        { "Refresh _Syntax Highlighting", update_lexing }
484
485    }
486
487    newkeys["f5"] = update_lexing
488
489    newkeys[OSX and "mp" or "cs\t"] = goto_prev_buffer
490    newkeys[OSX and "mn" or "c\t"]  = goto_next_buffer
491    newkeys[OSX and "mb" or "cb"]   = ui.switch_buffer
492
493end
494
495do
496
497    local function toggle_current_fold()
498        buffer:toggle_fold(buffer:line_from_position(buffer.current_pos))
499    end
500
501    local function toggle_show_guides()
502        local off = buffer.indentation_guides == 0
503        buffer.indentation_guides = off and buffer.IV_LOOKBOTH or 0
504    end
505
506    local function toggle_virtual_space()
507        local off = buffer.virtual_space_options == 0
508        buffer.virtual_space_options = off and buffer.VS_USERACCESSIBLE or 0
509    end
510
511    local function reset_zoom()
512        buffer.zoom = 0
513    end
514
515    newmenu.view = {
516
517        title = "_View",
518
519        SEPARATOR,
520
521        { "Toggle Current _Fold" ,      toggle_current_fold },
522
523        SEPARATOR,
524
525        { "Toggle Show In_dent Guides", toggle_show_guides },
526        { "Toggle _Virtual Space",      toggle_virtual_space },
527
528        SEPARATOR,
529
530        { "Zoom _In",                   buffer.zoom_in },
531        { "Zoom _Out",                  buffer.zoom_out },
532        { "_Reset Zoom",                reset_zoom },
533
534    }
535
536    newkeys[OSX and "m=" or "c="] = buffer.zoom_in
537    newkeys[OSX and "m-" or "c-"] = buffer.zoom_out
538    newkeys[OSX and "m0" or "c0"] = reset_zoom
539
540end
541
542do
543
544    -- It"s a pitt y that we can"t have a proper monospaced font here so we try to make the best of it:
545
546    local template = "\n\trelease info: %s\t\n\n\tcopyright: %s\t\n\n\tvariant: ConTeXt related editing\t\n\n\tadapted by: Hans Hagen\t"
547
548    function show_about()
549        ui.dialogs.msgbox {
550            title            = "about",
551            informative_text = format(template,(gsub(_RELEASE,"%s+"," ")),(gsub(_COPYRIGHT,"%s+"," ")))
552        }
553    end
554
555    local function open_url(url) -- adapted from non public open_page
556        local cmd = (WIN32 and 'start ""') or (OSX and "open") or "xdg-open"
557        os.spawn(format('%s "%s"', cmd, url))
558    end
559
560
561    newmenu.help = {
562
563        title = "_Help",
564
565        SEPARATOR,
566
567        { "ConTeXt garden wiki", function() open_url("http://www.contextgarden.net") end },
568
569     -- SEPARATOR,
570
571        { "_About", show_about }
572
573    }
574
575end
576
577do 
578
579    -- from shift F11 and startup script 
580
581    table.insert(textadept.menu.context_menu, SEPARATOR)
582
583    table.insert(textadept.menu.context_menu, { "wrap",     runner.wrap })
584    table.insert(textadept.menu.context_menu, { "unwrap",   runner.unwrap })
585    table.insert(textadept.menu.context_menu, { "sort",     runner.sort })
586 -- table.insert(textadept.menu.context_menu, { "document", function() end })
587 -- table.insert(textadept.menu.context_menu, { "quote",    function() end })
588 -- table.insert(textadept.menu.context_menu, { "compound", function() end })
589 -- table.insert(textadept.menu.context_menu, { "add",      function() end })
590 -- table.insert(textadept.menu.context_menu, { "bidi",     function() end })
591 -- table.insert(textadept.menu.context_menu, { "strip",    function() end })
592
593
594 -- cM wrap 
595 -- cR reset spelling 
596 -- cI insert template  
597 -- cE show log 
598 -- c+ toggle strip 
599
600    newkeys[OSX and "mm" or "cm"] = runner.wrap
601
602end
603
604do
605
606    local function replace(oldmenu,newmenu)
607        local n = #newmenu
608        local o = #oldmenu
609        for i=1,n do
610            oldmenu[i] = newmenu[i]
611        end
612        for i=o,n+1,-1 do
613            oldmenu[i] = nil
614        end
615    end
616
617    replace(textadept.menu.menubar [_L["_File"]],   newmenu.file)
618    replace(textadept.menu.menubar [_L["_Edit"]],   newmenu.edit)
619    replace(textadept.menu.menubar [_L["_Search"]], newmenu.search)
620    replace(textadept.menu.menubar [_L["_Tools"]],  newmenu.tools)
621    replace(textadept.menu.menubar [_L["_Buffer"]], newmenu.buffer)
622    replace(textadept.menu.menubar [_L["_View"]],   newmenu.view)
623    replace(textadept.menu.menubar [_L["_Help"]],   newmenu.help)
624
625    local char = string.char
626
627    local combi = {
628        "c", "m", "a",
629        "cm", "ca", "ma",
630    }
631
632    local pad   = {
633        "esc", "del", "bs",
634        "up", "down", "left", "right",
635        "end", "home",
636        "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12",
637    }
638
639    local s = "s"
640
641    for i=1,#combi do
642        local c = combi[i]
643        for i=0x20,0x40 do
644            local ci = char(i)
645            keys[   c..ci] = nil
646            keys[s..c..ci] = nil
647        end
648        for i=0x41,0x5A do -- A .. Z
649            local ci = char(i)
650            keys[   c..ci] = nil
651        end
652        for i=0x5B,0x60 do
653            local ci = char(i)
654            keys[   c..ci] = nil
655            keys[s..c..ci] = nil
656        end
657        for i=0x61,0x7A do -- a .. z
658            local ci = char(i)
659            keys[   c..ci] = nil
660        end
661        for i=0x7B,0x7F do
662            local ci = char(i)
663            keys[   c..ci] = nil
664            keys[s..c..ci] = nil
665        end
666        for i=1,#pad do
667            local pi = pad[i]
668            keys[   c..pi] = nil
669            keys[s..c..pi] = nil
670        end
671    end
672
673    for k, v in next, newkeys do
674        keys[k] = v
675    end
676
677    -- add helper to textadept-context-runner.lua instead 
678
679    events.connect(events.INITIALIZED, function()
680        for i=1,#_BUFFERS do
681            local buffer = _BUFFERS[i]
682            if buffer._type == OUTPUT_BUFFER then
683                view:goto_buffer(i)
684                io.close_buffer()
685                return 
686            end 
687        end
688    end)
689
690end
691
692-- We have a different way to set up files and runners. Less distributed and morein the way we
693-- do things in context.
694
695local dummyrunner    = function() end
696local extensions     = textadept.file_types.extensions
697local specifications = runner.specifications
698local setters        = { }
699local defaults       = {
700    check   = dummyrunner,
701    process = dummyrunner,
702    preview = dummyrunner,
703}
704
705setmetatable(specifications, { __index = defaults })
706
707function context.install(specification)
708    local suffixes = specification.suffixes
709    if suffixes then
710        local lexer    = specification.lexer
711        local setter   = specification.setter
712        local encoding = specification.encoding
713        for i=1,#suffixes do
714            local suffix = suffixes[i]
715            if lexer and extensions then
716                extensions[suffix] = lexer
717            end
718            specifications[suffix] = specification
719            if lexer then
720                setters[lexer] = function()
721                    if encoding == "7-BIT-ASCII" then
722                        setsevenbitascii(buffer)
723                    end
724                    if setter then
725                        setter(lexer)
726                    end
727                end
728            end
729        end
730    end
731end
732
733-- Too much interference so I might drop all the old stuff eventually.
734
735local function synchronize(lexer)
736    if lexer then
737        local setter = lexer and setters[lexer]
738        if setter then
739            local action = context.synchronize
740            if action then
741                action()
742            end
743         -- userunner()
744            setter(lexer)
745        else
746         -- useoldrunner()
747        end
748    end
749end
750
751events.connect(events.FILE_OPENED,function(filename)
752    synchronize(buffer:get_lexer())
753end)
754
755events.connect(events.LEXER_LOADED,function(lexer)
756    synchronize(lexer)
757end)
758
759-- obsolete
760
761-- events.connect(events.BUFFER_AFTER_SWITCH,function()
762--     synchronize(buffer:get_lexer())
763-- end)
764
765-- events.connect(events.VIEW_AFTER_SWITCH,function()
766--     synchronize(buffer:get_lexer())
767-- end)
768
769-- events.connect(events.BUFFER_NEW,function()
770--     synchronize(buffer:get_lexer())
771-- end)
772
773-- events.connect(events.VIEW_NEW,function()
774--     synchronize(buffer:get_lexer())
775-- end)
776
777-- events.connect(events.RESET_AFTER,function()
778--     synchronize(buffer:get_lexer())
779-- end)
780
781-- local oldtools  = { }
782-- local usingold  = false
783-- local toolsmenu = textadept.menu.menubar [_L['_Tools']]
784--
785-- for i=1,#toolsmenu do
786--     oldtools[i] = toolsmenu[i]
787-- end
788--
789-- local function replace(tools)
790--     local n = #toolsmenu
791--     local m = #tools
792--     for i=1,m do
793--         toolsmenu[i] = tools[i]
794--     end
795--     for i=n,m+1,-1 do
796--         toolsmenu[i] = nil
797--     end
798-- end
799--
800-- local function useoldrunner()
801--     if not usingold then
802--         keys [OSX and 'mr' or                  'cr'  ] = oldrunner.run
803--         keys [OSX and 'mR' or (GUI and 'cR' or 'cmr')] = oldrunner.compile
804--         keys [OSX and 'mB' or (GUI and 'cB' or 'cmb')] = oldrunner.build
805--         keys [OSX and 'mX' or (GUI and 'cX' or 'cmx')] = oldrunner.stop
806--         --
807--         replace(oldtools)
808--         --
809--         usingold = true
810--     end
811-- end
812--
813-- local function userunner()
814--     if usingold then
815--         keys [OSX and 'mr' or                  'cr'  ] = runner.process
816--         keys [OSX and 'mR' or (GUI and 'cR' or 'cmr')] = runner.check
817--         keys [OSX and 'mB' or (GUI and 'cB' or 'cmb')] = runner.preview
818--         keys [OSX and 'mX' or (GUI and 'cX' or 'cmx')] = runner.quit
819--         --
820--         replace(newtools)
821--         --
822--         usingold = false
823--     end
824-- end
825--
826-- userunner()
827