summary refs log tree commit diff stats
path: root/compiler/modulepaths.nim
blob: e80ea3fa66329bc72b4eae7a4d746ab5ed0bb06b (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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#
#
#           The Nim Compiler
#        (c) Copyright 2017 Contributors
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

import ast, renderer, strutils, msgs, options, idents, os, lineinfos,
  pathutils

proc getModuleName*(conf: ConfigRef; n: PNode): string =
  # This returns a short relative module name without the nim extension
  # e.g. like "system", "importer" or "somepath/module"
  # The proc won't perform any checks that the path is actually valid
  case n.kind
  of nkStrLit, nkRStrLit, nkTripleStrLit:
    try:
      result = pathSubs(conf, n.strVal, toFullPath(conf, n.info).splitFile().dir)
    except ValueError:
      localError(conf, n.info, "invalid path: " & n.strVal)
      result = n.strVal
  of nkIdent:
    result = n.ident.s
  of nkSym:
    result = n.sym.name.s
  of nkInfix:
    let n0 = n[0]
    let n1 = n[1]
    when false:
      if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$":
        if n0.kind == nkIdent and n0.ident.s == "/":
          result = lookupPackage(n1[1], n[2])
        else:
          localError(n.info, "only '/' supported with $package notation")
          result = ""
    else:
      let modname = getModuleName(conf, n[2])
      # hacky way to implement 'x / y /../ z':
      result = getModuleName(conf, n1)
      result.add renderTree(n0, {renderNoComments}).replace(" ")
      result.add modname
  of nkPrefix:
    when false:
      if n[0].kind == nkIdent and n[0].ident.s == "$":
        result = lookupPackage(n[1], nil)
      else:
        discard
    # hacky way to implement 'x / y /../ z':
    result = renderTree(n, {renderNoComments}).replace(" ")
  of nkDotExpr:
    localError(conf, n.info, warnDeprecated, "using '.' instead of '/' in import paths is deprecated")
    result = renderTree(n, {renderNoComments}).replace(".", "/")
  of nkImportAs:
    result = getModuleName(conf, n[0])
  else:
    localError(conf, n.info, "invalid module name: '$1'" % n.renderTree)
    result = ""

proc checkModuleName*(conf: ConfigRef; n: PNode; doLocalError=true): FileIndex =
  # This returns the full canonical path for a given module import
  let modulename = getModuleName(conf, n)
  let fullPath = findModule(conf, modulename, toFullPath(conf, n.info))
  if fullPath.isEmpty:
    if doLocalError:
      let m = if modulename.len > 0: modulename else: $n
      localError(conf, n.info, "cannot open file: " & m)
    result = InvalidFileIdx
  else:
    result = fileInfoIdx(conf, fullPath)

proc mangleModuleName*(conf: ConfigRef; path: AbsoluteFile): string =
  ## Mangle a relative module path to avoid path and symbol collisions.
  ##
  ## Used by backends that need to generate intermediary files from Nim modules.
  ## This is needed because the compiler uses a flat cache file hierarchy.
  ##
  ## Example:
  ## `foo-#head/../bar` becomes `@foo-@hhead@s..@sbar`
  "@m" & relativeTo(path, conf.projectPath).string.multiReplace(
    {$os.DirSep: "@s", $os.AltSep: "@s", "#": "@h", "@": "@@", ":": "@c"})

proc demangleModuleName*(path: string): string =
  ## Demangle a relative module path.
  result = path.multiReplace({"@@": "@", "@h": "#", "@s": "/", "@m": "", "@c": ":"})
">{ MODKEY, XK_Tab, view, {0} }, { MODKEY, XK_q, killclient, {0} }, { MODKEY, XK_m, setlayout, {0} }, { MODKEY|ShiftMask, XK_f, togglefloating, {0} }, { MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, { MODKEY, XK_comma, focusmon, {.i = -1 } }, { MODKEY, XK_period, focusmon, {.i = +1 } }, { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) TAGKEYS( XK_4, 3) TAGKEYS( XK_5, 4) TAGKEYS( XK_6, 5) TAGKEYS( XK_7, 6) TAGKEYS( XK_8, 7) TAGKEYS( XK_9, 8) { MODKEY|ShiftMask, XK_q, quit, {0} }, /* programs */ { MODKEY, XK_w, spawn, SHCMD("firefox") }, { MODKEY, XK_f, spawn, SHCMD("st ranger") }, { ControlMask|ShiftMask, XK_Escape, spawn, SHCMD("st btop") }, /* volume control */ { 0, XF86XK_AudioRaiseVolume, spawn, SHCMD("pamixer -i 5; kill -35 $(pidof dwmblocks)") }, { 0, XF86XK_AudioLowerVolume, spawn, SHCMD("pamixer -d 5; kill -35 $(pidof dwmblocks)") }, { 0, XF86XK_AudioMute, spawn, SHCMD("pamixer -t; kill -35 $(pidof dwmblocks)") }, /* brightness control */ { 0, XF86XK_MonBrightnessUp, spawn, SHCMD("light -A 5") }, { 0, XF86XK_MonBrightnessDown, spawn, SHCMD("light -U 5") }, /* screenshots with scrotre */ { 0, XK_Print, spawn, SHCMD("scrotre -C") }, { ShiftMask, XK_Print, spawn, SHCMD("scrotre '$HOME/Изображения/Скриншоты/%Y-%m-%d-%H%M%S_$wx$h_scrotre.png'") }, { ControlMask, XK_Print, spawn, SHCMD("scrotre -sC") }, { ControlMask|ShiftMask, XK_Print, spawn, SHCMD("scrotre -s '$HOME/Изображения/Скриншоты/%Y-%m-%d-%H%M%S_$wx$h_scrotre.png'") }, /* MPRIS */ { 0, XF86XK_AudioPlay, spawn, SHCMD("playerctl play-pause") }, { 0, XF86XK_AudioStop, spawn, SHCMD("playerctl stop") }, { 0, XF86XK_AudioPrev, spawn, SHCMD("playerctl previous") }, { 0, XF86XK_AudioNext, spawn, SHCMD("playerctl next") }, /* misc */ { 0, XF86XK_TouchpadToggle, spawn, SHCMD("tp-toggle") }, /* movestack patch */ { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, /* vim keys */ { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, { MODKEY|ShiftMask, XK_Down, movestack, {.i = +1 } }, /* arrow keys */ { MODKEY|ShiftMask, XK_Up, movestack, {.i = -1 } }, /* focusurgent patch */ { MODKEY, XK_a, focusurgent, {0} }, }; /* button definitions */ /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ static const Button buttons[] = { /* click event mask button function argument */ { ClkLtSymbol, 0, Button1, setlayout, {0} }, // { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, { ClkWinTitle, 0, Button2, zoom, {0} }, { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, { ClkClientWin, MODKEY, Button1, movemouse, {0} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, { ClkTagBar, 0, Button1, view, {0} }, { ClkTagBar, 0, Button3, toggleview, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} }, };