1 -- Luakit configuration file, more information at http://luakit.org/
7 -- Widget construction aliases
8 function eventbox() return widget
{type="eventbox"} end
9 function hbox() return widget
{type="hbox"} end
10 function label() return widget
{type="label"} end
11 function notebook() return widget
{type="notebook"} end
12 function vbox() return widget
{type="vbox"} end
13 function webview() return widget
{type="webview"} end
14 function window() return widget
{type="window"} end
15 function entry() return widget
{type="entry"} end
17 -- Variable definitions
18 HOMEPAGE
= "http://luakit.org/"
19 --HOMEPAGE = "http://github.com/mason-larobina/luakit"
22 MAX_SRCH_HISTORY
= 100
27 font
= "monospace normal 9",
32 statusbar_fg
= "#fff",
33 statusbar_bg
= "#000",
38 loaded_fg
= "#33AADD",
41 selected_tablabel_fg
= "#fff",
42 selected_tablabel_bg
= "#000",
44 -- Enforce a minimum tab width of 30 characters to prevent longer tab
45 -- titles overshadowing small tab titles when things get crowded.
46 tablabel_format
= "%-30s",
49 widget
.add_signal("new", function(wi
)
50 wi
:add_signal("init", function(wi
)
51 if wi
.type == "window" then
52 wi
:add_signal("destroy", function ()
53 -- Call the quit function if this was the last window left
54 if #luakit
.windows
== 0 then luakit
.quit() end
62 google
= "http://google.com/search?q={0}",
63 imdb
= "http://imdb.com/find?s=all&q={0}",
64 sourceforge
= "http://sf.net/search/?words={0}"
67 -- Add key bindings to be used across all windows
69 -- bind.buf(Pattern, function (w, buffer, opts) .. end, opts),
70 -- bind.key({Modifiers}, Key name, function (w, opts) .. end, opts),
72 bind
.key({}, "Escape", function (w
) w
:set_mode() end),
73 bind
.key({"Control"}, "[", function (w
) w
:set_mode() end),
76 bind
.key({}, "i", function (w
) w
:set_mode("insert") end),
77 bind
.key({}, ":", function (w
) w
:set_mode("command") end),
80 bind
.key({}, "h", function (w
) w
:scroll_horiz("-"..SCROLL_STEP
.."px") end),
81 bind
.key({}, "j", function (w
) w
:scroll_vert ("+"..SCROLL_STEP
.."px") end),
82 bind
.key({}, "k", function (w
) w
:scroll_vert ("-"..SCROLL_STEP
.."px") end),
83 bind
.key({}, "l", function (w
) w
:scroll_horiz("+"..SCROLL_STEP
.."px") end),
84 bind
.key({}, "Left", function (w
) w
:scroll_horiz("-"..SCROLL_STEP
.."px") end),
85 bind
.key({}, "Down", function (w
) w
:scroll_vert ("+"..SCROLL_STEP
.."px") end),
86 bind
.key({}, "Up", function (w
) w
:scroll_vert ("-"..SCROLL_STEP
.."px") end),
87 bind
.key({}, "Right", function (w
) w
:scroll_horiz("+"..SCROLL_STEP
.."px") end),
88 bind
.buf("^gg$", function (w
) w
:scroll_vert("0%") end),
89 bind
.buf("^G$", function (w
) w
:scroll_vert("100%") end),
90 bind
.buf("^[\-\+]?[0-9]+[%%G]$", function (w
, b
) w
:scroll_vert(string.match(b
, "^([\-\+]?%d+)[%%G]$") .. "%") end),
93 bind
.buf("^o$", function (w
, c
) w
:enter_cmd(":open ") end),
94 bind
.buf("^t$", function (w
, c
) w
:enter_cmd(":tabopen ") end),
95 bind
.buf("^,g$", function (w
, c
) w
:enter_cmd(":websearch google ") end),
98 bind
.key({}, "/", function (w
) w
:start_search(true) end),
99 bind
.key({}, "?", function (w
) w
:start_search(false) end),
100 bind
.key({}, "n", function (w
) w
:search(nil, true) end),
101 bind
.key({}, "N", function (w
) w
:search(nil, false) end),
104 bind
.buf("^[0-9]*H$", function (w
, b
) w
:back (tonumber(string.match(b
, "^(%d*)H$") or 1)) end),
105 bind
.buf("^[0-9]*L$", function (w
, b
) w
:forward(tonumber(string.match(b
, "^(%d*)L$") or 1)) end),
108 bind
.buf("^[0-9]*gT$", function (w
, b
) w
:prev_tab(tonumber(string.match(b
, "^(%d*)gT$") or 1)) end),
109 bind
.buf("^[0-9]*gt$", function (w
, b
) w
:next_tab(tonumber(string.match(b
, "^(%d*)gt$") or 1)) end),
110 bind
.buf("^gH$", function (w
) w
:new_tab(HOMEPAGE
) end),
111 bind
.buf("^d$", function (w
) w
:close_tab() end),
113 bind
.buf("^gh$", function (w
) w
:navigate(HOMEPAGE
) end),
114 bind
.buf("^ZZ$", function (w
) luakit
.quit() end),
117 bind
.key({}, "Up", function (w
) w
:cmd_hist_prev() end),
118 bind
.key({}, "Down", function (w
) w
:cmd_hist_next() end),
119 bind
.key({}, "Tab", function (w
) w
:cmd_completion() end),
120 bind
.key({"Control"}, "w", function (w
) w
:del_word() end),
121 bind
.key({"Control"}, "u", function (w
) w
:del_line() end),
124 bind
.key({}, "Up", function (w
) w
:srch_hist_prev() end),
125 bind
.key({}, "Down", function (w
) w
:srch_hist_next() end),
132 -- bind.cmd({Command, Alias1, ...}, function (w, arg, opts) .. end, opts),
133 bind
.cmd({"open", "o"}, function (w
, a
) w
:navigate(a
) end),
134 bind
.cmd({"tabopen", "t"}, function (w
, a
) w
:new_tab(a
) end),
135 bind
.cmd({"back" }, function (w
, a
) w
:back(tonumber(a
) or 1) end),
136 bind
.cmd({"forward", "f"}, function (w
, a
) w
:forward(tonumber(a
) or 1) end),
137 bind
.cmd({"scroll" }, function (w
, a
) w
:scroll_vert(a
) end),
138 bind
.cmd({"quit", "q"}, function (w
) luakit
.quit() end),
139 bind
.cmd({"close", "c"}, function (w
) w
:close_tab() end),
140 bind
.cmd({"websearch", "ws"}, function (w
, e
, s
) w
:websearch(e
, s
) end),
143 -- Build and pack window widgets
144 function build_window()
145 -- Create a table for widgets and state variables for a window
157 -- Status bar widgets
161 -- Left aligned widgets
168 -- Fills space between the left and right aligned widgets
170 -- Right aligned widgets
189 w
.ebox
:set_child(w
.layout
)
190 w
.win
:set_child(w
.ebox
)
194 t
.ebox
:set_child(t
.layout
, false, false, 0)
195 w
.layout
:pack_start(t
.ebox
, false, false, 0)
198 w
.layout
:pack_start(w
.tabs
, true, true, 0)
200 -- Pack left-aligned statusbar elements
202 l
.layout
:pack_start(l
.uri
, false, false, 0)
203 l
.layout
:pack_start(l
.loaded
, false, false, 0)
204 l
.ebox
:set_child(l
.layout
)
206 -- Pack right-aligned statusbar elements
208 r
.layout
:pack_start(r
.buf
, false, false, 0)
209 r
.layout
:pack_start(r
.tabi
, false, false, 0)
210 r
.layout
:pack_start(r
.scroll
, false, false, 0)
211 r
.ebox
:set_child(r
.layout
)
213 -- Pack status bar elements
215 s
.layout
:pack_start(l
.ebox
, false, false, 0)
216 s
.layout
:pack_start(s
.filler
, true, true, 0)
217 s
.layout
:pack_start(r
.ebox
, false, false, 0)
218 s
.ebox
:set_child(s
.layout
)
219 w
.layout
:pack_start(s
.ebox
, false, false, 0)
223 i
.layout
:pack_start(i
.prompt
, false, false, 0)
224 i
.layout
:pack_start(i
.input
, true, true, 0)
225 i
.ebox
:set_child(i
.layout
)
226 w
.layout
:pack_start(i
.ebox
, false, false, 0)
229 i
.input
.show_frame
= false
230 w
.tabs
.show_tabs
= false
232 l
.uri
.selectable
= true
237 function attach_window_signals(w
)
238 -- Attach notebook widget signals
239 w
.tabs
:add_signal("page-added", function(nbook
, view
, idx
)
240 w
:update_tab_count(idx
)
241 w
:update_tab_labels()
244 w
.tabs
:add_signal("switch-page", function(nbook
, view
, idx
)
245 w
:update_tab_count(idx
)
246 w
:update_win_title(view
)
248 w
:update_progress(view
)
249 w
:update_tab_labels(idx
)
252 -- Attach window widget signals
253 w
.win
:add_signal("key-press", function(win
, mods
, key
)
254 -- Reset command line completion
255 if w
:get_mode() == "command" and key
~= "Tab" and w
.compl_start
then
260 if w
:hit(mods
, key
) then
265 w
.win
:add_signal("mode-changed", function(win
, mode
)
267 w
.cmd_hist_cursor
= nil
269 -- If a user aborts a search return to the original position
270 if w
.search_start_marker
then
271 w
:get_current():set_scroll_vert(w
.search_start_marker
)
272 w
.search_start_marker
= nil
275 if mode
== "normal" then
278 elseif mode
== "insert" then
280 w
.ibar
.input
.text
= ""
281 w
.ibar
.prompt
.text
= "-- INSERT --"
283 elseif mode
== "command" then
285 w
.ibar
.input
.text
= ":"
288 w
.ibar
.input
:set_position(-1)
289 elseif mode
== "search" then
293 w
.ibar
.prompt
.text
= ""
294 w
.ibar
.input
.text
= ""
298 -- Attach inputbar widget signals
299 w
.ibar
.input
:add_signal("changed", function()
300 local text
= w
.ibar
.input
.text
301 -- Auto-exit "command" mode if you backspace or delete the ":"
302 -- character at the start of the input box when in "command" mode.
303 if w
:is_mode("command") and not string.match(text
, "^:") then
305 elseif w
:is_mode("search") then
306 if string.match(text
, "^[\?\/]") then
307 w
:search(string.sub(text
, 2), (string.sub(text
, 1, 1) == "/"))
315 w
.ibar
.input
:add_signal("activate", function()
316 local text
= w
.ibar
.input
.text
317 if w
:is_mode("command") then
319 w
:match_cmd(string.sub(text
, 2))
321 elseif w
:is_mode("search") then
322 w
:srch_hist_add(text
)
323 w
:search(string.sub(text
, 2), string.sub(text
, 1, 1) == "/")
324 -- User doesn't want to return to start position
325 w
.search_start_marker
= nil
327 w
.ibar
.prompt
.text
= text
333 -- Attach signal handlers to a new tab's webview
334 function attach_webview_signals(w
, view
)
335 view
:add_signal("title-changed", function (v
)
336 w
:update_tab_labels()
337 if w
:is_current(v
) then
338 w
:update_win_title(v
)
342 view
:add_signal("property::uri", function(v
)
343 w
:update_tab_labels()
344 if w
:is_current(v
) then
349 view
:add_signal("key-press", function ()
350 -- Only allow key press events to hit the webview if the user is in
352 if not w
:is_mode("insert") then
357 view
:add_signal("load-start", function (v
)
358 if w
:is_current(v
) then
359 w
:update_progress(v
, 0)
364 view
:add_signal("progress-update", function (v
)
365 if w
:is_current(v
) then
370 view
:add_signal("expose", function(v
)
371 if w
:is_current(v
) then
377 -- Parses scroll amounts of the form:
378 -- Relative: "+20%", "-20%", "+20px", "-20px"
379 -- Absolute: 20, "20%", "20px"
380 -- And returns an absolute value.
381 function parse_scroll(current
, max, value
)
382 if string.match(value
, "^%d+px$") then
383 return tonumber(string.match(value
, "^(%d+)px$"))
384 elseif string.match(value
, "^%d+%%$") then
385 return math
.ceil(max * (tonumber(string.match(value
, "^(%d+)%%$")) / 100))
386 elseif string.match(value
, "^[\-\+]%d+px") then
387 return current
+ tonumber(string.match(value
, "^([\-\+]%d+)px"))
388 elseif string.match(value
, "^[\-\+]%d+%%$") then
389 return math
.ceil(current
+ (max * (tonumber(string.match(value
, "^([\-\+]%d+)%%$")) / 100)))
391 print("E: unable to parse scroll amount:", value
)
395 -- Helper functions which operate on a windows widget structure
397 -- Return the widget in the currently active tab
398 get_current
= function(w
) return w
.tabs
:atindex(w
.tabs
:current()) end,
399 -- Check if given widget is the widget in the currently active tab
400 is_current
= function(w
, wi
) return w
.tabs
:indexof(wi
) == w
.tabs
:current() end,
402 -- Wrappers around the mode plugin
403 set_mode
= function(w
, name
) mode
.set(w
.win
, name
) end,
404 get_mode
= function(w
) return mode
.get(w
.win
) end,
405 is_mode
= function(w
, name
) return name
== w
:get_mode() end,
406 is_any_mode
= function(w
, t
, name
) return util
.table.hasitem(t
, name
or w
:get_mode()) end,
408 -- Wrappers around the view:get_prop & view:set_prop methods
409 get
= function (w
, prop
, view
)
410 if not view
then view
= w
:get_current() end
411 return view
:get_prop(prop
)
414 set
= function (w
, prop
, val
, view
)
415 if not view
then view
= w
:get_current() end
416 view
:set_prop(prop
, val
)
419 get_tab_title
= function (w
, view
)
420 if not view
then view
= w
:get_current() end
421 return view
:get_prop("title") or view
.uri
or "(Untitled)"
424 navigate
= function(w
, uri
, view
)
425 local v
= view
or w
:get_current()
429 return w
:new_tab(uri
)
433 new_tab
= function(w
, uri
)
434 local view
= webview()
436 attach_webview_signals(w
, view
)
437 if uri
then view
.uri
= uri
end
438 view
.show_scrollbars
= false
442 -- close the current tab
443 close_tab
= function(w
)
444 view
= w
:get_current()
445 if not view
then return end
451 -- Wrapper around the bind plugin's hit method
452 hit
= function (w
, mods
, key
)
453 local caught
, newbuf
= bind
.hit(w
.binds
or {}, mods
, key
, w
.buffer
, w
:is_mode("normal"), w
)
459 -- Wrapper around the bind plugin's match_cmd method
460 match_cmd
= function (w
, buffer
)
461 return bind
.match_cmd(commands
, buffer
, w
)
464 -- enter command or characters into command line
465 enter_cmd
= function(w
, cmd
)
466 local i
= w
.ibar
.input
467 w
:set_mode("command")
472 -- search engine wrapper
473 websearch
= function(w
, args
)
474 local sep
= string.find(args
, " ")
475 local engine
= string.sub(args
, 1, sep
-1)
476 local search
= string.sub(args
, sep
+1)
477 if not search_engines
[engine
] then
478 print("E: No matching search engine found:", engine
)
481 local uri
= string.gsub(search_engines
[engine
], "{%d}", search
)
482 return w
:navigate(uri
)
485 -- Command line completion of available commands
486 cmd_completion
= function(w
)
487 local i
= w
.ibar
.input
488 local s
= w
.sbar
.l
.uri
491 -- Get last completion (is reset on key press other than <Tab>)
492 if not w
.compl_start
or w
.compl_index
== 0 then
493 w
.compl_start
= "^" .. string.sub(i
.text
, 2)
497 -- Get suitable commands
498 for _
, b
in ipairs(commands
) do
499 for _
, c
in pairs(b
.commands
) do
500 if c
and string.match(c
, w
.compl_start
) then
501 table.insert(cmpl
, c
)
510 for index
, comp
in pairs(cmpl
) do
511 if index
== w
.compl_index
then
512 i
.text
= ":" .. comp
.. " "
521 -- cycle through all possible completions
522 if w
.compl_index
== #cmpl
then
525 w
.compl_index
= w
.compl_index
+ 1
531 del_word
= function(w
)
532 local i
= w
.ibar
.input
534 local pos
= i
:get_position()
535 if text
and #text
> 1 and pos
> 1 then
536 local left
, right
= string.sub(text
, 2, pos
), string.sub(text
, pos
+1)
537 if not string.find(left
, "%s") then
539 elseif string.find(left
, "%w+%s*$") then
540 left
= string.sub(left
, 0, string.find(left
, "%w+%s*$") - 1)
541 elseif string.find(left
, "%W+%s*$") then
542 left
= string.sub(left
, 0, string.find(left
, "%W+%s*$") - 1)
544 i
.text
= string.sub(text
, 1, 1) .. left
.. right
545 i
:set_position(#left
+ 2)
549 del_line
= function(w
)
550 local i
= w
.ibar
.input
551 if i
.text
~= ":" then
557 -- Search history adding
558 srch_hist_add
= function(w
, srch
)
559 if not w
.srch_hist
then w
.srch_hist
= {} end
561 if #w
.srch_hist
> ((MAX_SRCH_HISTORY
or 100) + 5) then
562 while #w
.srch_hist
> (MAX_SRCH_HISTORY
or 100) do
563 table.remove(w
.srch_hist
, 1)
566 table.insert(w
.srch_hist
, srch
)
569 -- Search history traversing
570 srch_hist_prev
= function(w
)
571 if not w
.srch_hist
then w
.srch_hist
= {} end
572 if not w
.srch_hist_cursor
then
573 w
.srch_hist_cursor
= #w
.srch_hist
+ 1
574 w
.srch_hist_current
= w
.ibar
.input
.text
576 local c
= w
.srch_hist_cursor
- 1
577 if w
.srch_hist
[c
] then
578 w
.srch_hist_cursor
= c
579 w
.ibar
.input
.text
= w
.srch_hist
[c
]
580 w
.ibar
.input
:set_position(-1)
584 srch_hist_next
= function(w
)
585 if not w
.srch_hist
then w
.srch_hist
= {} end
586 local c
= (w
.srch_hist_cursor
or #w
.srch_hist
) + 1
587 if w
.srch_hist
[c
] then
588 w
.srch_hist_cursor
= c
589 w
.ibar
.input
.text
= w
.srch_hist
[c
]
590 w
.ibar
.input
:set_position(-1)
591 elseif w
.srch_hist_current
then
592 w
.srch_hist_cursor
= nil
593 w
.ibar
.input
.text
= w
.srch_hist_current
594 w
.ibar
.input
:set_position(-1)
598 -- Command history adding
599 cmd_hist_add
= function(w
, cmd
)
600 if not w
.cmd_hist
then w
.cmd_hist
= {} end
601 -- Make sure history doesn't overflow
602 if #w
.cmd_hist
> ((MAX_CMD_HISTORY
or 100) + 5) then
603 while #w
.cmd_hist
> (MAX_CMD_HISTORY
or 100) do
604 table.remove(w
.cmd_hist
, 1)
607 table.insert(w
.cmd_hist
, cmd
)
610 -- Command history traversing
611 cmd_hist_prev
= function(w
)
612 if not w
.cmd_hist
then w
.cmd_hist
= {} end
613 if not w
.cmd_hist_cursor
then
614 w
.cmd_hist_cursor
= #w
.cmd_hist
+ 1
615 w
.cmd_hist_current
= w
.ibar
.input
.text
617 local c
= w
.cmd_hist_cursor
- 1
618 if w
.cmd_hist
[c
] then
619 w
.cmd_hist_cursor
= c
620 w
.ibar
.input
.text
= w
.cmd_hist
[c
]
621 w
.ibar
.input
:set_position(-1)
625 cmd_hist_next
= function(w
)
626 if not w
.cmd_hist
then w
.cmd_hist
= {} end
627 local c
= (w
.cmd_hist_cursor
or #w
.cmd_hist
) + 1
628 if w
.cmd_hist
[c
] then
629 w
.cmd_hist_cursor
= c
630 w
.ibar
.input
.text
= w
.cmd_hist
[c
]
631 w
.ibar
.input
:set_position(-1)
632 elseif w
.cmd_hist_current
then
633 w
.cmd_hist_cursor
= nil
634 w
.ibar
.input
.text
= w
.cmd_hist_current
635 w
.ibar
.input
:set_position(-1)
639 -- Searching functions
640 start_search
= function(w
, forward
)
641 -- Clear previous search results
644 local i
= w
.ibar
.input
654 search
= function(w
, text
, forward
)
655 local view
= w
:get_current()
656 local text
= text
or w
.last_search
657 if forward
== nil then forward
= true end
658 local case_sensitive
= false
661 if not text
or #text
== 0 then
667 if w
.searching_forward
== nil then
668 w
.searching_forward
= forward
669 w
.search_start_marker
= view
:get_scroll_vert()
671 -- Invert the direction if originally searching in reverse
672 forward
= (w
.searching_forward
== forward
)
675 view
:search(text
, case_sensitive
, forward
, wrap
);
678 clear_search
= function (w
)
679 w
:get_current():clear_search()
680 -- Clear search state
682 w
.searching_forward
= nil
683 w
.search_start_marker
= nil
686 -- Webview scroll functions
687 scroll_vert
= function(w
, value
, view
)
688 if not view
then view
= w
:get_current() end
689 local cur
, max = view
:get_scroll_vert()
690 if type(value
) == "string" then
691 value
= parse_scroll(cur
, max, value
)
693 view
:set_scroll_vert(value
)
696 scroll_horiz
= function(w
, value
)
697 if not view
then view
= w
:get_current() end
698 local cur
, max = view
:get_scroll_horiz()
699 if type(value
) == "string" then
700 value
= parse_scroll(cur
, max, value
)
702 view
:set_scroll_horiz(value
)
705 -- Tab traversing functions
706 next_tab
= function(w
, n
)
707 w
.tabs
:switch((((n
or 1) + w
.tabs
:current() -1) % w
.tabs
:count()) + 1)
709 prev_tab
= function(w
, n
)
710 w
.tabs
:switch(((w
.tabs
:current() - (n
or 1) -1) % w
.tabs
:count()) + 1)
712 goto_tab
= function(w
, n
)
716 -- History traversing functions
717 back
= function(w
, n
, view
)
718 (view
or w
:get_current()):go_back(n
or 1)
720 forward
= function(w
, n
, view
)
721 (view
or w
:get_current()):go_forward(n
or 1)
724 -- GUI content update functions
725 update_tab_count
= function (w
, i
, t
)
726 w
.sbar
.r
.tabi
.text
= string.format("[%d/%d]", i
or w
.tabs
:current(), t
or w
.tabs
:count())
729 update_win_title
= function (w
, view
)
730 if not view
then view
= w
:get_current() end
731 local title
= view
:get_prop("title")
733 if not title
and not uri
then
734 w
.win
.title
= "luakit"
736 w
.win
.title
= (title
or "luakit") .. " - " .. (uri
or "about:blank")
740 update_uri
= function (w
, view
, uri
)
741 if not view
then view
= w
:get_current() end
742 w
.sbar
.l
.uri
.text
= (uri
or view
.uri
or "about:blank")
745 update_progress
= function (w
, view
, p
)
746 if not view
then view
= w
:get_current() end
747 if not p
then p
= view
:get_prop("progress") end
748 if not view
:loading() or p
== 1 then
749 w
.sbar
.l
.loaded
:hide()
751 w
.sbar
.l
.loaded
:show()
752 w
.sbar
.l
.loaded
.text
= string.format("(%d%%)", p
* 100)
756 update_scroll
= function (w
, view
)
757 if not view
then view
= w
:get_current() end
758 local val
, max = view
:get_scroll_vert()
759 if max == 0 then val
= "All"
760 elseif val
== 0 then val
= "Top"
761 elseif val
== max then val
= "Bot"
762 else val
= string.format("%2d%%", (val
/max) * 100)
764 w
.sbar
.r
.scroll
.text
= val
767 update_buf
= function (w
)
769 w
.sbar
.r
.buf
.text
= string.format(" %-3s", w
.buffer
)
776 update_binds
= function (w
, mode
)
777 -- Generate the list of active key & buffer binds for this mode
778 w
.binds
= util
.table.join(mode_binds
[mode
], mode_binds
.all
)
779 -- Clear & hide buffer
784 -- Tab label functions
785 make_tab_label
= function (w
, pos
)
792 t
.label
.font
= theme
.tablabel_font
or theme
.font
793 t
.layout
:pack_start(t
.label
, true, true, 0)
794 t
.layout
:pack_start(t
.sep
, false, false, 0)
795 t
.ebox
:set_child(t
.layout
)
796 t
.ebox
:add_signal("clicked", function(e
) w
.tabs
:switch(pos
) end)
800 destroy_tab_label
= function(w
, t
)
801 if not t
then t
= table.remove(w
.tbar
.titles
) end
802 for _
, wi
in pairs(t
) do
807 update_tab_labels
= function (w
, current
)
809 local count
, current
= w
.tabs
:count(), current
or w
.tabs
:current()
812 -- Leave the tablist hidden if there is only one tab open
817 if count
~= #tb
.titles
then
818 -- Grow the number of labels
819 while count
> #tb
.titles
do
820 local t
= w
:make_tab_label(#tb
.titles
+ 1)
821 tb
.layout
:pack_start(t
.ebox
, true, true, 0)
822 table.insert(tb
.titles
, t
)
824 -- Prune number of labels
825 while count
< #tb
.titles
do
826 w
:destroy_tab_label()
832 local t
= tb
.titles
[i
]
833 local title
= " " ..i
.. " "..w
:get_tab_title(w
.tabs
:atindex(i
))
834 t
.label
.text
= string.format(theme
.tablabel_format
or "%s", title
)
835 w
:apply_tablabel_theme(t
, i
== current
)
842 apply_tablabel_theme
= function (w
, t
, selected
, atheme
)
843 local theme
= atheme
or theme
845 t
.label
.fg
= theme
.selected_tablabel_fg
or theme
.tablabel_fg
or theme
.fg
846 t
.ebox
.bg
= theme
.selected_tablabel_bg
or theme
.tablabel_bg
or theme
.bg
848 t
.label
.fg
= theme
.tablabel_fg
or theme
.fg
849 t
.ebox
.bg
= theme
.tablabel_bg
or theme
.bg
853 apply_window_theme
= function (w
, atheme
)
854 local theme
= atheme
or theme
855 local s
, i
, t
= w
.sbar
, w
.ibar
, w
.tbar
856 local fg
, bg
, font
= theme
.fg
, theme
.bg
, theme
.font
860 [s
.l
.uri
] = theme
.uri_fg
or theme
.statusbar_fg
or fg
,
861 [s
.l
.loaded
] = theme
.loaded_fg
or theme
.statusbar_fg
or fg
,
862 [s
.r
.buf
] = theme
.buf_fg
or theme
.statusbar_fg
or fg
,
863 [s
.r
.tabi
] = theme
.tabi_fg
or theme
.statusbar_fg
or fg
,
864 [s
.r
.scroll
] = theme
.scroll_fg
or theme
.statusbar_fg
or fg
,
865 [i
.prompt
] = theme
.prompt_fg
or theme
.inputbar_fg
or fg
,
866 [i
.input
] = theme
.input_fg
or theme
.inputbar_fg
or fg
,
871 [s
.l
.ebox
] = theme
.statusbar_bg
or bg
,
872 [s
.r
.ebox
] = theme
.statusbar_bg
or bg
,
873 [s
.ebox
] = theme
.statusbar_bg
or bg
,
874 [i
.ebox
] = theme
.inputbar_bg
or bg
,
875 [i
.input
] = theme
.input_bg
or theme
.inputbar_bg
or bg
,
880 [s
.l
.uri
] = theme
.uri_font
or theme
.statusbar_font
or font
,
881 [s
.l
.loaded
] = theme
.loaded_font
or theme
.statusbar_font
or font
,
882 [s
.r
.buf
] = theme
.buf_font
or theme
.statusbar_font
or font
,
883 [s
.r
.tabi
] = theme
.tabi_font
or theme
.statusbar_font
or font
,
884 [s
.r
.scroll
] = theme
.scroll_font
or theme
.statusbar_font
or font
,
885 [i
.prompt
] = theme
.prompt_font
or theme
.inputbar_font
or font
,
886 [i
.input
] = theme
.input_font
or theme
.inputbar_font
or font
,
887 }) do wi
.font
= v
end
892 function new_window(uris
)
893 local w
= build_window()
895 -- Pack the window table full of the common helper functions
896 for k
, v
in pairs(window_helpers
) do w
[k
] = v
end
898 attach_window_signals(w
)
900 -- Apply window theme
901 w
:apply_window_theme()
903 -- Populate notebook with tabs
904 for _
, uri
in ipairs(uris
or {}) do
908 -- Make sure something is loaded
909 if w
.tabs
:count() == 0 then
921 -- vim: ft=lua:et:sw=4:ts=8:sts=4:tw=80