Sublimetext2 相对于缩进的升华文本排序

Sublimetext2 相对于缩进的升华文本排序,sublimetext2,sublimetext3,sublime-text-plugin,Sublimetext2,Sublimetext3,Sublime Text Plugin,我正在寻找一个崇高的文本插件或任何类型的程序,可以排序字母,但尊重缩进 比如说, beatsByUserPath: (userId) -> "/api/beats/by_user/#{userId}" sendMassMessagePath: -> "/api/send_mass_message" sendMessagePath: (userId) -> "/api/send_message/#{userId}" feedbackCreatePath: ->

我正在寻找一个崇高的文本插件或任何类型的程序,可以排序字母,但尊重缩进

比如说,

beatsByUserPath: (userId) ->
  "/api/beats/by_user/#{userId}"
sendMassMessagePath: ->
  "/api/send_mass_message"
sendMessagePath: (userId) ->
  "/api/send_message/#{userId}"
feedbackCreatePath: ->
  "/api/feedbacks"
将按函数名进行排序。 在升华文本中使用默认排序会导致:

  "/api/beats/by_user/#{userId}"
  "/api/feedbacks"
  "/api/send_mass_message"
  "/api/send_message/#{userId}"
beatsByUserPath: (userId) ->
feedbackCreatePath: ->
sendMassMessagePath: ->
sendMessagePath: (userId) ->
这是我想要排序的完整文件

RouteHelper =
  EXTERNAL:
    soundcloudConvertPath: (url) ->
      url = encodeURIComponent(url)
      "http://streampocket.com/?stream=#{url}"
    youtubeConvertPath: (url) ->
      url = encodeURIComponent(url)
      "http://www.video2mp3.net/loading.php?url=#{url}"
  UTIL:
    imageProxy: (url) ->
      url = encodeURIComponent(url)
      "/image-proxy/#{url}"
  API:
    beatsReportPath: (param) ->
      beatId = param
      beatId = param.id if typeof param is 'object' && param.id
      "/api/beats/#{beatId}/report"
    beatsTrackDownloadPath: (param) ->
      beatId = param
      beatId = param.id if typeof param is 'object' && param.id
      "/api/beats/#{beatId}/track_download"
    beatSetDownloadPath: (param) ->
      beatId = param
      beatId = param.id if typeof param is 'object' && param.id
      "/api/beats/#{beatId}/set_download_url"
    beatsToggleVisibilityPath: (param) ->
      beatId = param
      beatId = param.id if typeof param is 'object' && param.id
      "/api/beats/#{beatId}/toggle_visibility"
    beatsToggleRecordingPath: (param) ->
      beatId = param
      beatId = param.id if typeof param is 'object' && param.id
      "/api/beats/#{beatId}/toggle_recording"
    beatsDisownPath: (param) ->
      beatId = param
      beatId = param.id if typeof param is 'object' && param.id
      "/api/beats/#{beatId}/disown"
    beatsEditNotePath: (param) ->
      beatId = param
      beatId = param.id if typeof param is 'object' && param.id
      "/api/beats/#{beatId}/edit_note"
    beatsByUserPath: (userId) ->
      "/api/beats/by_user/#{userId}"
    discussPath: ->
      "/api/discuss"
    sendMassMessagePath: ->
      "/api/send_mass_message"
    sendMessagePath: (userId) ->
      "/api/send_message/#{userId}"
    feedbackCreatePath: ->
      "/api/feedbacks"
    feedbacksForRapPath: (arg) ->
      rapId = if typeof rap is 'object' then arg.id else arg
      "/api/feedbacks/feedback_for/#{rapId}"
    followersPath: (userId) ->
      "/api/followers/#{userId}"
    followingPath: (userId) ->
      "/api/following/#{userId}"
    followPath: (userId) ->
      "/api/follow/#{userId}"
    unfollowPath: (userId) ->
      "/api/unfollow/#{userId}"
    propsPath: ->
      "/api/props"
    userBattlesPath_deprecated: (userId) ->
      "/api/battles/for_user/#{userId}"
    battlesLeaderboardPath: ->
      "/api/battles/leaderboard"
    battlesUsersWhoVotedForPath: (opts) ->
      throw Error('RouteHelper: Expected ID and WHICH') if !opts.id || !opts.which
      "/api/battles/#{opts.id}/users_who_voted_for/#{opts.which}"
    rapProppersPath: (rapId) ->
      "/api/raps/#{rapId}/proppers"
    rapUntagPath: (rapId) ->
      "/api/raps/#{rapId}/untag"
    rapShowPath: (param) ->
      if typeof param is 'object'
        rapId = param.id
      else rapId = param
      "/api/raps/#{rapId}/show_v2"
    userPinPath: ->
      "/api/users/pin"
    userBattlesPath: (userId) ->
      "/api/users/#{userId}/battles"
    userBeatsPath: (userId) ->
      "/api/users/#{userId}/beats"
    userRapsPath: (userId) ->
      "/api/users/#{userId}/raps_v2"
    userSetColorsPath: (userId) ->
      "/api/users/#{userId}/set_colors"
    userShowPath: (userId) ->
      "/api/users/#{userId}"
    usersWhoGaveProps: (userId) ->
      "/api/users/#{userId}/users_who_gave_props"
    userUnreadNotifCount: (userId) ->
      "/api/users/#{userId}/unread_notif_count"
    userRecordNetegoPath: ->
      "/api/users/record_net_ego"
  albumShowPath: (param) ->
    param = param.slug if _.isObject(param)
    "/albums/#{param}"
  blueprintShowPathFromRap: (rap) ->
    "/blueprints/#{rap.blueprint_id}"
  battleDestroyPath: (battle) ->
    "/battles/#{battle.id}"
  battlesPath: ->
    "/battles"
  battleNewPath: ->
    "/battles/new"
  battleShowPath: (battle) ->
    "/battles/#{battle.id}"
  beatNewPath: ->
    "/beats/new"
  beatShowPath: (beat) ->
    if typeof beat is 'number'
      "/beats/#{beat}"
    else if typeof beat is 'object'
      if beat.slug
        "/beats/#{beat.slug}"
      else
        "/beats/#{beat.id}"
  beatTagShowPath: (beatTag) ->
    "#{beatTag.slug}/instrumentals"
  beatsSearchQueryPath: ->
    "/beats/search_query"
  beatsRecentSearchesPath: ->
    "/beats/recent_searches"
  cypherJudgeVotePath: ->
    "/cyphers/judge-vote"
  cypherJudgeShowPath: ->
    "/cyphers/judge-show"
  cypherSubmitPath: ->
    "/cyphers/submit"
  dashboardPath: ->
    "/dashboard"
  defaultRapThumbnailPath: ->
    "/images/default_rap.png"
  rhymePath: ->
    "/rhyme"
  contextPath: ->
    "/context"
  searchLyricsPath: ->
    "/rap/search_lyrics"
  editorSavePath: ->
    "/editor/save"
  editorPath: (param) ->
    param = param.id if typeof param is 'object'
    if param
      "/editor/#{param}"
    else
      "/editor"
  onRapSaveDialogPath: (rapId) ->
    "/rap/#{rapId}/on_save_dialog"
  lyricSyncSavePath: ->
    "/lyric-sync/save"
  lyricSyncDestroyPath: ->
    "/lyric-sync/destroy"
  notificationsPath: ->
    "/notifications"
  rapEditPath: (rap) ->
    "/editor/#{rap.id}"
  rapShowPath: (rap) ->
    "/rap/#{rap.id}"
  rapsForCypher: (cypherId) ->
    "/cyphers/#{cypherId}/submissions"
  isSubscribedPath: (listId) ->
    "/is_subscribed/#{listId}"
  subscribeToPath: (listId) ->
    "/subscribe_to/#{listId}"
  userShowPath: (username) ->
    "/users/#{username}"
  userNotificationSettingPath: ->
    "/users/notification_setting"

@RouteHelper = RouteHelper

我不知道有什么通用的解决方案,因为块的定义(用于排序)高度依赖于上下文

但是,对于您发布的特定案例,可以通过简单的宏通过以下步骤轻松完成:

  • 将每个块合并为一行(用
    ->
    替换出现的
    ->\n
  • 单行排序
  • 将每一个块从一行取消合并回原来的缩进形式(将每一次出现的
    ->
    替换为
    ->\n
  • 唯一的问题是,Sublime不会在宏中记录查找和替换命令。相反,我们需要安装
    RegReplace
    包,该包提供可以记录在宏中的find&replace命令。(有关安装说明,请参阅)

    一旦安装了
    RegReplace
    ,只需将以下两个文件放在数据目录中的
    Packages/User/
    下()

    现在,您可以通过从顶部菜单中选择
    Tools->Macros->smart\u sort
    来运行
    smart\u sort

    免责声明:如果每个函数的缩进行数超过1行,则需要相应地调整正则表达式定义

    智能排序。升华宏
    (宏)
    reg\u替换。崇高设置
    (reg\u替换定义)

    在看到更新后的问题和完整文件的示例后,我继续创建了一个Sublime文本插件,其中包含一些控制排序的基本选项

  • 从软件包控制安装
    indentreserverSort
    (有关说明,请参阅)
  • 通过
    Ctrl+`
    Cmd打开控制台(⌘) + `(OSX)
  • 假设您的文件如问题中所述缩进了2个空格,并且您只想对函数名进行排序,请键入

    view.run_command("indent_respectful_sort", {"indent": "  ", "onlyDepth" : 3})
    
    进入控制台并点击
    Enter
    。这将仅对函数名进行排序,同时考虑结构的其余部分


  • 如果您想使用不同的选项进行排序,您可以参考插件页面查看更多选项。

    您是否总是每个缩进块有一行或可能每个块有多行?我想知道您是否只想在不破坏结构的情况下对函数名进行排序,还是也要对其块相应的缩进行进行排序。是的,你不想对缩进的块进行排序,只想对顶级块(即函数名)进行排序,在这种情况下,它们总是1行。我想你提出了一个有效的观点,以及为什么这样的功能还不存在。File“/Applications/Sublime Text 3 Beta.app/Contents/MacOS/Sublime\u plugin.py”,第550行,在run_uuu返回self.run(编辑,**参数)文件“indentredirectfulsort in/Users/amirsharif/Library/Application Support/Sublime Text 3/Installed Packages/Indent redirectful Sort.Sublime package”中,第14行,在run AttributeError:“module”对象没有属性“maxint”回溯(最近一次调用):文件“/Applications/Sublime Text 3 Beta.app/Contents/MacOS/Sublime_plugin.py”,我现在已经修复了它。包控制可能需要一段时间来检测更新。同时,您可以直接从github存储库提取更新的包。
    {
        "replacements": {
            "merge_block_into_a_line": {
                "find": "->\\n",
                "replace": "->",
                "greedy": true,
                "case": true
            },
            "restore_block": {
                "find": "->",
                "replace": "->\\n",
                "greedy": true,
                "case": true
            }
        }
    }
    
    view.run_command("indent_respectful_sort", {"indent": "  ", "onlyDepth" : 3})