summary refs log tree commit diff stats
path: root/compiler/idgen.nim
blob: 3c5669b541dbfd5ec5b5ca34654c3610ce4d1be6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#
#
#           The Nim Compiler
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## This module contains a simple persistent id generator.

import idents, strutils, os, options

var gFrontEndId, gBackendId*: int

const
  debugIds* = false

when debugIds:
  import intsets
  
  var usedIds = initIntSet()

proc registerID*(id: PIdObj) = 
  when debugIds: 
    if id.id == -1 or containsOrIncl(usedIds, id.id): 
      internalError("ID already used: " & $id.id)

proc getID*(): int {.inline.} = 
  result = gFrontEndId
  inc(gFrontEndId)

proc backendId*(): int {.inline.} = 
  result = gBackendId
  inc(gBackendId)

proc setId*(id: int) {.inline.} = 
  gFrontEndId = max(gFrontEndId, id + 1)

proc idSynchronizationPoint*(idRange: int) = 
  gFrontEndId = (gFrontEndId div idRange + 1) * idRange + 1

proc toGid(f: string): string =
  # we used to use ``f.addFileExt("gid")`` (aka ``$project.gid``), but this
  # will cause strange bugs if multiple projects are in the same folder, so
  # we simply use a project independent name:
  result = options.completeGeneratedFilePath("nimrod.gid")

proc saveMaxIds*(project: string) =
  var f = open(project.toGid, fmWrite)
  f.writeln($gFrontEndId)
  f.writeln($gBackendId)
  f.close()
  
proc loadMaxIds*(project: string) =
  var f: File
  if open(f, project.toGid, fmRead):
    var line = newStringOfCap(20)
    if f.readLine(line):
      var frontEndId = parseInt(line)
      if f.readLine(line):
        var backEndId = parseInt(line)
        gFrontEndId = max(gFrontEndId, frontEndId)
        gBackendId = max(gBackendId, backEndId)
    f.close()
an class="o">.add_child(self.pager) self.change_ratios(ratios, resize=False) for option in ('preview_directories', 'preview_files'): self.settings.signal_bind('setopt.' + option, self._request_clear_if_has_borders, weak=True) self.fm.env.signal_bind('move', self.request_clear) self.settings.signal_bind('setopt.column_ratios', self.request_clear) def change_ratios(self, ratios, resize=True): if isinstance(ratios, Signal): ratios = ratios.value for column in self.columns: column.destroy() self.remove_child(column) self.columns = [] ratio_sum = float(sum(ratios)) self.ratios = tuple(x / ratio_sum for x in ratios) last = 0.1 if self.settings.padding_right else 0 if len(self.ratios) >= 2: self.stretch_ratios = self.ratios[:-2] + \ ((self.ratios[-2] + self.ratios[-1] * 1.0 - last), (self.ratios[-1] * last)) offset = 1 - len(ratios) if self.preview: offset += 1 for level in range(len(ratios)): fl = BrowserColumn(self.win, level + offset) self.add_child(fl) self.columns.append(fl) try: self.main_column = self.columns[self.preview and -2 or -1] except IndexError: self.main_column = None else: self.main_column.display_infostring = True self.main_column.main_column = True self.resize(self.y, self.x, self.hei, self.wid) def _request_clear_if_has_borders(self): if self.settings.draw_borders: self.request_clear() def request_clear(self): self.need_clear = True def draw(self): if self.draw_bookmarks: self._draw_bookmarks() else: if self.need_clear: self.win.erase() self.need_redraw = True self.need_clear = False DisplayableContainer.draw(self) if self.settings.draw_borders: self._draw_borders() def finalize(self): if self.pager.visible: try: self.fm.ui.win.move(self.main_column.y, self.main_column.x) except: pass else: try: x = self.main_column.x y = self.main_column.y + self.main_column.target.pointer\ - self.main_column.scroll_begin self.fm.ui.win.move(y, x) except: pass def _draw_bookmarks(self): self.fm.bookmarks.update_if_outdated() self.color_reset() self.need_clear = True sorted_bookmarks = sorted(item for item in self.fm.bookmarks \ if self.settings.show_hidden_bookmarks or '/.' not in item[1].path) def generator(): return zip(range(self.hei-1), sorted_bookmarks) try: maxlen = max(len(item[1].path) for i, item in generator()) except ValueError: return maxlen = min(maxlen + 5, self.wid) whitespace = " " * maxlen for line, items in generator(): key, mark = items string = " " + key + ": " + mark.path self.addstr(line, 0, whitespace) self.addnstr(line, 0, string, self.wid) if self.settings.draw_bookmark_borders: self.win.hline(line+1, 0, curses.ACS_HLINE, maxlen) if maxlen < self.wid: self.win.vline(0, maxlen, curses.ACS_VLINE, line+1) self.addch(line+1, maxlen, curses.ACS_LRCORNER) def _draw_borders(self): win = self.win self.color('in_browser', 'border') left_start = 0 right_end = self.wid - 1 for child in self.columns: if not child.has_preview(): left_start = child.x + child.wid else: break if not self.pager.visible: for child in reversed(self.columns): if not child.has_preview(): right_end = child.x - 1 else: break if right_end < left_start: right_end = self.wid - 1 win.hline(0, left_start, curses.ACS_HLINE, right_end - left_start) win.hline(self.hei - 1, left_start, curses.ACS_HLINE, right_end - left_start) win.vline(1, left_start, curses.ACS_VLINE, self.hei - 2) for child in self.columns: if not child.has_preview(): continue if child.main_column and self.pager.visible: win.vline(1, right_end, curses.ACS_VLINE, self.hei - 2) break x = child.x + child.wid y = self.hei - 1 try: win.vline(1, x, curses.ACS_VLINE, y - 1) win.addch(0, x, curses.ACS_TTEE, 0) win.addch(y, x, curses.ACS_BTEE, 0) except: # in case it's off the boundaries pass self.addch(0, left_start, curses.ACS_ULCORNER) self.addch(self.hei - 1, left_start, curses.ACS_LLCORNER) self.addch(0, right_end, curses.ACS_URCORNER) self.addch(self.hei - 1, right_end, curses.ACS_LRCORNER) def _collapse(self): # Should the last column be cut off? (Because there is no preview) if not self.settings.collapse_preview or not self.preview \ or not self.stretch_ratios: return False result = not self.columns[-1].has_preview() target = self.columns[-1].target if not result and target and target.is_file and \ self.fm.settings.preview_script and \ self.fm.settings.use_preview_script: try: result = not self.fm.previews[target.realpath]['foundpreview'] except: return self.old_collapse self.old_collapse = result return result def resize(self, y, x, hei, wid): """Resize all the columns according to the given ratio""" DisplayableContainer.resize(self, y, x, hei, wid) borders = self.settings.draw_borders pad = 1 if borders else 0 left = pad self.is_collapsed = self._collapse() if self.is_collapsed: generator = enumerate(self.stretch_ratios) else: generator = enumerate(self.ratios) last_i = len(self.ratios) - 1 for i, ratio in generator: wid = int(ratio * self.wid) cut_off = self.is_collapsed and not self.settings.padding_right if i == last_i: if not cut_off: wid = int(self.wid - left + 1 - pad) else: self.columns[i].resize(pad, left - 1, hei - pad * 2, 1) self.columns[i].visible = False continue if i == last_i - 1: self.pager.resize(pad, left, hei - pad * 2, \ max(1, self.wid - left - pad)) if cut_off: self.columns[i].resize(pad, left, hei - pad * 2, \ max(1, self.wid - left - pad)) continue try: self.columns[i].resize(pad, left, hei - pad * 2, \ max(1, wid - 1)) except KeyError: pass left += wid def click(self, event): if DisplayableContainer.click(self, event): return True direction = event.mouse_wheel_direction() if direction: self.main_column.scroll(direction) return False def open_pager(self): self.pager.visible = True self.pager.focused = True self.need_clear = True self.pager.open() try: self.columns[-1].visible = False self.columns[-2].visible = False except IndexError: pass def close_pager(self): self.pager.visible = False self.pager.focused = False self.need_clear = True self.pager.close() try: self.columns[-1].visible = True self.columns[-2].visible = True except IndexError: pass def poke(self): DisplayableContainer.poke(self) # Show the preview column when it has a preview but has # been hidden (e.g. because of padding_right = False) if not self.pager.visible and not self.columns[-1].visible and \ self.columns[-1].target and self.columns[-1].target.is_directory \ or self.columns[-1].has_preview() and not self.pager.visible: self.columns[-1].visible = True if self.preview and self.is_collapsed != self._collapse(): self.resize(self.y, self.x, self.hei, self.wid)