2014-05-08 21 views
15

Chế độ Emacs C++ mặc định (cc-mode) vẫn không nhận ra nhiều tính năng C++ 11. Một vấn đề gây phiền nhiễu là nó sử dụng quá nhiều thụt đầu dòng để các hàm lambda sử dụng như thông số chức năng:Emacs thụt vào hàm lambda C++ 11 (chế độ cc)

std::vector<int> ar(4); 
std::generate_n(std::begin(ar), 4, [] { 
     static int g_i; 
     return g_i++; 
    }); 
std::for_each(std::begin(ar), std::end(ar), [](int i) { 
     std::cout << " " << i; 
    }); 
bool b = std::is_sorted(std::begin(ar), std::end(ar), [&](int l, int r) { 
     return l<r; 
    }); 
std::cout << " " << b << "\n"; 

Lý tưởng nhất, người ta sẽ thích:

std::vector<int> ar(4); 
std::generate_n(std::begin(ar), 4, [] { 
    static int g_i; 
    return g_i++; 
}); 
std::for_each(std::begin(ar), std::end(ar), [](int i) { 
    std::cout << " " << i; 
}); 
bool b = std::is_sorted(std::begin(ar), std::end(ar), [&](int l, int r) { 
    return l<r; 
}); 
std::cout << " " << b << "\n"; 

Có các giải pháp tốt cho việc này?

+0

Bạn nên sử dụng ['std :: iota'] (http://en.cppreference.com/w/cpp/algorithm/iota) thay vì lệnh 'generate_n' bằng biến' static'. – Praetorian

+0

Sử dụng tính năng thụt lề gỗ. Tiếp tục thụt dòng trước đó, sử dụng các lệnh thủ công để lùi/thụt lề. Tại 1 khóa mỗi phần chi phí của một dòng, là nó thực sự giá trị duy trì và đối phó với quirks của một mã toàn bộ mã định dạng mã? Tôi có nghĩa là gọn gàng và tất cả, và đôi khi hữu ích cho bản sao/mì ống ... – Yakk

+0

@Praetorian Nó được dự định như là một ví dụ nhanh chóng của một hàm lambda không có đối số. Hàm 'std :: iota' không sử dụng tham số hàm. – Hugues

Trả lời

14

Cuộc thảo luận trong Emacs cc-mode indentation problem with C++0x enum class khắc phục sự cố định dạng enum class định dạng.

Điều này đã lấy cảm hứng từ chức năng tư vấn sau. Nó sẽ phát hiện một C mở ++ chức năng lambda trong một danh sách đối số mở, và hủy bỏ một mức độ thụt đầu dòng để tạo ra kết quả "lý tưởng" trong câu hỏi:

(defadvice c-lineup-arglist (around my activate) 
    "Improve indentation of continued C++11 lambda function opened as argument." 
    (setq ad-return-value 
     (if (and (equal major-mode 'c++-mode) 
       (ignore-errors 
        (save-excursion 
        (goto-char (c-langelem-pos langelem)) 
        ;; Detect "[...](" or "[...]{". preceded by "," or "(", 
        ;; and with unclosed brace. 
        (looking-at ".*[(,][ \t]*\\[[^]]*\\][ \t]*[({][^}]*$")))) 
      0       ; no additional indent 
      ad-do-it)))     ; default behavior 
+0

Tôi có thể chỉ cần thêm điều này vào .emac của tôi để làm cho nó hoạt động không? Đó là chính xác những gì tôi muốn, nhưng không có vấn đề làm thế nào tôi thêm nó vào môi trường của tôi, nó không làm bất cứ điều gì. – Mike

+0

@Mike Có, nó sẽ hoạt động ngay khi chức năng tư vấn được đánh giá. Bạn có thể thử gọi '(C++ - mode)' trên bộ đệm hoạt động của bạn để đảm bảo nó đang ở chế độ chính xác. Ngoài ra '(c-version)' sẽ hiển thị chế độ cc hiện tại (đối với tôi nó là 5.32.4). – Hugues

3

Một rework nhẹ giải pháp của Hugues để cũng nhận lambda hàm là đối số được lồng trong hàm lambda khác và hàm lambda dưới dạng giá trị khởi tạo trong lớp:

(defun vr-c++-looking-at-lambda_as_param() 
    "Return t if text after point matches '[...](' or '[...]{'" 
    (looking-at ".*[,(][ \t]*\\[[^]]*\\][ \t]*[({][^}]*?[ \t]*[({][^}]*?$")) 

(defun vr-c++-looking-at-lambda_in_uniform_init() 
    "Return t if text after point matches '{[...](' or '{[...]{'" 
    (looking-at ".*{[ \t]*\\[[^]]*\\][ \t]*[({][^}]*?[ \t]*[({][^}]*?$")) 

(defun vr-c++-indentation-examine (langelem looking-at-p) 
    (and (equal major-mode 'c++-mode) 
     (ignore-errors 
     (save-excursion 
      (goto-char (c-langelem-pos langelem)) 
      (funcall looking-at-p))))) 

(defun vr-c++-indentation-setup() 
    (require 'google-c-style) 
    (google-set-c-style) 

    (c-set-offset 
    'block-close 
    (lambda (langelem) 
    (if (vr-c++-indentation-examine 
      langelem 
      #'vr-c++-looking-at-lambda_in_uniform_init) 
     '- 
     0))) 

    (c-set-offset 
    'statement-block-intro 
    (lambda (langelem) 
    (if (vr-c++-indentation-examine 
      langelem 
      #'vr-c++-looking-at-lambda_in_uniform_init) 
     0 
     '+))) 

    (defadvice c-lineup-arglist (around my activate) 
    "Improve indentation of continued C++11 lambda function opened as argument." 
    (setq ad-return-value 
      (if (vr-c++-indentation-examine 
       langelem 
       #'vr-c++-looking-at-lambda_as_param) 
       0 
      ad-do-it)))) 
Các vấn đề liên quan